class HtmlFileWriter(_DataFileWriter): def __init__(self, configuration): formatter = HtmlFormatter(configuration.html_column_count) _DataFileWriter.__init__(self, formatter, configuration) self._name = configuration.datafile.name self._writer = HtmlWriter(configuration.output) def write(self, datafile): self._writer.content(TEMPLATE_START % {'NAME': self._name}, escape=False) _DataFileWriter.write(self, datafile) self._writer.content(TEMPLATE_END, escape=False) def _write_table(self, table, is_last): self._writer.start('table', {'id': table.type.replace(' ', ''), 'border': '1'}) _DataFileWriter._write_table(self, table, is_last) self._writer.end('table') def _write_row(self, row): self._writer.start('tr') for cell in row: self._writer.element(cell.tag, cell.content, cell.attributes, escape=False) self._writer.end('tr')
def test_line_separator(self): output = StringIO() writer = HtmlWriter(output) writer.start('b') writer.end('b') writer.element('i') assert_equal(output.getvalue(), '<b>\n</b>\n<i></i>\n')
def _download_and_format_issues(): try: from robot.utils import HtmlWriter, html_format except ImportError: sys.exit('creating release requires Robot Framework to be installed.') URL = Template('http://code.google.com/p/robotframework-ride/issues/csv?' 'sort=priority+type&colspec=ID%20Type%20Priority%20Summary' '&q=target%3A${version}&can=1') reader = csv.reader(urlopen(URL.substitute({'version': VERSION}))) total_issues = 0 writer = HtmlWriter(StringIO()) writer.element('h2', 'Release notes for %s' % VERSION) writer.start('table', attrs={'border': '1'}) for row in reader: if not row or row[1] == 'Task': continue row = row[:4] writer.start('tr') if reader.line_num == 1: row = [ '*%s*' % cell for cell in row ] else: row[0] = '<a href="http://code.google.com/p/robotframework-ride/'\ 'issues/detail?id=%s">Issue %s</a>' % (row[0], row[0]) total_issues += 1 for cell in row: if reader.line_num == 1: cell = html_format(cell) writer.element('td', cell, escape=False) writer.end('tr') writer.end('table') writer.element('p', 'Altogether %d issues.' % total_issues) return writer.output.getvalue()
def test_line_separator(self): output = StringIO() writer = HtmlWriter(output) writer.start('b') writer.end('b') writer.element('i') assert_equal(repr(output.getvalue()), repr('<b>\n</b>\n<i></i>\n'))
class HtmlFileWriter(_DataFileWriter): def __init__(self, configuration): formatter = HtmlFormatter(configuration.html_column_count) _DataFileWriter.__init__(self, formatter, configuration) self._name = configuration.datafile.name self._writer = HtmlWriter(configuration.output) def write(self, datafile): self._writer.content(TEMPLATE_START % {'NAME': self._name}, escape=False) _DataFileWriter.write(self, datafile) self._writer.content(TEMPLATE_END, escape=False) def _write_table(self, table, is_last): self._writer.start('table', { 'id': table.type.replace(' ', ''), 'border': '1' }) _DataFileWriter._write_table(self, table, is_last) self._writer.end('table') def _write_row(self, row): self._writer.start('tr') for cell in row: self._writer.element(cell.tag, cell.content, cell.attributes, escape=False) self._writer.end('tr')
def _download_and_format_issues(): try: from robot.utils import HtmlWriter, html_format except ImportError: sys.exit('creating release requires Robot Framework to be installed.') URL = Template('http://code.google.com/p/robotframework-ride/issues/csv?' 'sort=priority+type&colspec=ID%20Type%20Priority%20Summary' '&q=target%3A${version}&can=1') reader = csv.reader(urlopen(URL.substitute({'version': VERSION}))) total_issues = 0 writer = HtmlWriter(StringIO()) writer.element('h2', 'Release notes for %s' % VERSION) writer.start('table', attrs={'border': '1'}) for row in reader: if not row or row[1] == 'Task': continue row = row[:4] writer.start('tr') if reader.line_num == 1: row = ['*%s*' % cell for cell in row] else: row[0] = '<a href="http://code.google.com/p/robotframework-ride/'\ 'issues/detail?id=%s">Issue %s</a>' % (row[0], row[0]) total_issues += 1 for cell in row: if reader.line_num == 1: cell = html_format(cell) writer.element('td', cell, escape=False) writer.end('tr') writer.end('table') writer.element('p', 'Altogether %d issues.' % total_issues) return writer.output.getvalue()
def test_non_ascii(self): self.output = StringIO() writer = HtmlWriter(self.output) writer.start(u'p', attrs={'name': u'hyv\xe4\xe4'}, newline=False) writer.content(u'y\xf6') writer.element('i', u't\xe4', newline=False) writer.end('p', newline=False) self._verify(u'<p name="hyv\xe4\xe4">y\xf6<i>t\xe4</i></p>')
def _test_line_separator(self, linesep): output = StringIO() writer = HtmlWriter(output, line_separator=linesep) writer.start('b') writer.end('b') writer.element('i') expected = '<b>%(LS)s</b>%(LS)s<i></i>%(LS)s' % {'LS': linesep} assert_equals(repr(output.getvalue()), repr(expected))
def _test_encoding(self, encoding): self.output = StringIO() writer = HtmlWriter(self.output, encoding=encoding) writer.start(u'p', attrs={'name': u'hyv\xe4\xe4'}, newline=False) writer.content(u'y\xf6') writer.element('i', u't\xe4', newline=False) writer.end('p', newline=False) self._verify(u'<p name="hyv\xe4\xe4">y\xf6<i>t\xe4</i></p>'.encode(encoding))
def _test_encoding(self, encoding): self.output = StringIO() writer = HtmlWriter(self.output, encoding=encoding) writer.start(u'p', attrs={'name': u'hyv\xe4\xe4'}, newline=False) writer.content(u'y\xf6') writer.element('i', u't\xe4', newline=False) writer.end('p', newline=False) self._verify( u'<p name="hyv\xe4\xe4">y\xf6<i>t\xe4</i></p>'.encode(encoding))
def _download_and_format_issues(): try: from robot.utils import HtmlWriter, html_format except ImportError: sys.exit('creating release requires Robot Framework to be installed.') writer = HtmlWriter(StringIO()) writer.element('h2', 'Release notes for %s' % VERSION) writer.start('table', attrs={'border': '1'}) writer.start('tr') for header in ['ID', 'Type', 'Priority', 'Summary']: writer.element( 'td', html_format('*{}*'.format(header)), escape=False) writer.end('tr') issues = list(_get_issues()) for issue in issues: writer.start('tr') link_tmpl = '<a href="http://github.com/robotframework/RIDE/issues/{0}">Issue {0}</a>' row = [link_tmpl.format(issue.number), find_type(issue), find_priority(issue), issue.title] for cell in row: writer.element('td', cell, escape=False) writer.end('tr') writer.end('table') writer.element('p', 'Altogether %d issues.' % len(issues)) return writer.output.getvalue()
def _download_and_format_issues(): try: from robot.utils import HtmlWriter, html_format except ImportError: sys.exit('creating release requires Robot Framework to be installed.') writer = HtmlWriter(StringIO()) writer.element('h2', 'Release notes for %s' % VERSION) writer.start('table', attrs={'border': '1'}) writer.start('tr') for header in ['ID', 'Type', 'Priority', 'Summary']: writer.element('td', html_format('*{}*'.format(header)), escape=False) writer.end('tr') issues = list(_get_issues()) for issue in issues: writer.start('tr') link_tmpl = '<a href="http://github.com/robotframework/RIDE/issues/{0}">Issue {0}</a>' row = [ link_tmpl.format(issue.number), find_type(issue), find_priority(issue), issue.title ] for cell in row: writer.element('td', cell, escape=False) writer.end('tr') writer.end('table') writer.element('p', 'Altogether %d issues.' % len(issues)) return writer.output.getvalue()
class DiffReporter(object): def __init__(self, outpath=None, title=None, showDiffs=True, excludeMatch=False): self.outpath = os.path.abspath(outpath or 'robotdiff.html') self._title = title or 'Test Run Diff Report' self._writer = HtmlWriter(self.outpath) self._showDiffs = showDiffs self._excludeMatch = excludeMatch def report(self, results): self._start(results.column_names) for row in results.rows: self._write_row(row) self._end() def _start(self, columns): self._writer.content((START_HTML % { 'TITLE': self._title }).encode('utf-8'), escape=False) self._writer.start('tr') self._writer.element('th', 'Name', {'class': 'col_name'}) for name in columns: self._writer.element('th', name, {'class': 'col_status'}) self._writer.end('tr') def _write_row(self, row): diff = not 'all' in row.status if (self._excludeMatch and not diff): return self._writer.start('tr') self._write_name(row) for item in row: self._write_status(item, row) self._writer.end('tr') def _write_name(self, row): self._writer.element('td', row.name, { 'class': 'col_name ' + row.status, 'title': row.explanation }) def _write_status(self, item, row): if (self._showDiffs and hasattr(item, 'comparison') and row.status == 'diff'): self._writer.element( 'td', item.comparison.encode('utf-8').decode('utf-8'), {'class': 'col_status ' + item.status}, False) else: self._writer.element('td', item.name, {'class': 'col_status ' + item.status}) def _end(self): for tag in 'table', 'body', 'html': self._writer.end(tag) self._writer.close()
class DiffReporter(object): def __init__(self, outpath=None, title=None): self.outpath = os.path.abspath(outpath or 'robotdiff.html') self._title = title or 'Test Run Diff Report' self._writer = HtmlWriter(open(self.outpath, 'w')) def report(self, results): self._start(results.column_names) for row in results.rows: self._write_row(row) self._end() def _start(self, columns): self._writer.content(START_HTML % {'TITLE': self._title}, escape=False) self._writer.start('tr') self._writer.element('th', 'Name', {'class': 'col_name'}) for name in columns: self._writer.element('th', name, {'class': 'col_status'}) self._writer.end('tr') def _write_row(self, row): self._writer.start('tr') self._write_name(row) for item in row: self._write_status(item) self._writer.end('tr') def _write_name(self, row): self._writer.element('td', row.name, { 'class': 'col_name ' + row.status, 'title': row.explanation }) def _write_status(self, item): self._writer.element('td', item.name, {'class': 'col_status ' + item.status}) def _end(self): for tag in 'table', 'body', 'html': self._writer.end(tag) self._writer.close()
class DiffReporter(object): def __init__(self, outpath=None, title=None): self.outpath = os.path.abspath(outpath or 'robotdiff.html') self._title = title or 'Test Run Diff Report' self._writer = HtmlWriter(open(self.outpath, 'w')) def report(self, results): self._start(results.column_names) for row in results.rows: self._write_row(row) self._end() def _start(self, columns): self._writer.content(START_HTML % {'TITLE': self._title}, escape=False) self._writer.start('tr') self._writer.element('th', 'Name', {'class': 'col_name'}) for name in columns: self._writer.element('th', name, {'class': 'col_status'}) self._writer.end('tr') def _write_row(self, row): self._writer.start('tr') self._write_name(row) for item in row: self._write_status(item) self._writer.end('tr') def _write_name(self, row): self._writer.element('td', row.name, {'class': 'col_name ' + row.status, 'title': row.explanation}) def _write_status(self, item): self._writer.element('td', item.name, {'class': 'col_status ' + item.status}) def _end(self): for tag in 'table', 'body', 'html': self._writer.end(tag) self._writer.close()
def _download_and_format_issues(): try: from robot.utils import HtmlWriter, html_format except ImportError: sys.exit("creating release requires Robot Framework to be installed.") writer = HtmlWriter(StringIO()) writer.element("h2", "Release notes for %s" % VERSION) writer.start("table", attrs={"border": "1"}) writer.start("tr") for header in ["ID", "Type", "Priority", "Summary"]: writer.element("td", html_format("*{}*".format(header)), escape=False) writer.end("tr") issues = _get_issues() for issue in issues: writer.start("tr") link_tmpl = '<a href="http://github.com/robotframework/RIDE/issues/{0}">Issue {0}</a>' row = [link_tmpl.format(issue.number), _find_type(issue), _find_priority(issue), issue.title] for cell in row: writer.element("td", cell, escape=False) writer.end("tr") writer.end("table") writer.element("p", "Altogether %d issues." % len(issues)) return writer.output.getvalue()
class TestHtmlWriter(unittest.TestCase): def setUp(self): self.output = StringIO() self.writer = HtmlWriter(self.output) def test_start(self): self.writer.start('r') self._verify('<r>\n') def test_start_without_newline(self): self.writer.start('robot', newline=False) self._verify('<robot>') def test_start_with_attribute(self): self.writer.start('robot', {'name': 'Suite1'}, False) self._verify('<robot name="Suite1">') def test_start_with_attributes(self): self.writer.start('test', {'class': '123', 'x': 'y', 'a': 'z'}) self._verify('<test a="z" class="123" x="y">\n') def test_start_with_non_ascii_attributes(self): self.writer.start('test', {'name': u'\xA7', u'\xE4': u'\xA7'}) self._verify(u'<test name="\xA7" \xE4="\xA7">\n') def test_start_with_quotes_in_attribute_value(self): self.writer.start('x', {'q': '"', 'qs': '""""', 'a': "'"}, False) self._verify('<x a="\'" q=""" qs="""""">') def test_start_with_html_in_attribute_values(self): self.writer.start('x', {'1': '<', '2': '&', '3': '</html>'}, False) self._verify('<x 1="<" 2="&" 3="</html>">') def test_start_with_newlines_and_tabs_in_attribute_values(self): self.writer.start('x', { '1': '\n', '3': 'A\nB\tC', '2': '\t', '4': '\r\n' }, False) self._verify( '<x 1=" " 2="	" 3="A B	C" 4=" ">') def test_end(self): self.writer.start('robot', newline=False) self.writer.end('robot') self._verify('<robot></robot>\n') def test_end_without_newline(self): self.writer.start('robot', newline=False) self.writer.end('robot', newline=False) self._verify('<robot></robot>') def test_end_alone(self): self.writer.end('suite', newline=False) self._verify('</suite>') def test_content(self): self.writer.start('robot') self.writer.content('Hello world!') self._verify('<robot>\nHello world!') def test_content_with_non_ascii_data(self): self.writer.start('robot', newline=False) self.writer.content(u'Circle is 360\xB0. ') self.writer.content(u'Hyv\xE4\xE4 \xFC\xF6t\xE4!') self.writer.end('robot', newline=False) expected = u'Circle is 360\xB0. Hyv\xE4\xE4 \xFC\xF6t\xE4!' self._verify('<robot>%s</robot>' % expected) def test_multiple_content(self): self.writer.start('robot') self.writer.content('Hello world!') self.writer.content('Hi again!') self._verify('<robot>\nHello world!Hi again!') def test_content_with_chars_needing_escaping(self): self.writer.content('Me, "Myself" & I > U') self._verify('Me, "Myself" & I > U') def test_content_alone(self): self.writer.content('hello') self._verify('hello') def test_none_content(self): self.writer.start('robot') self.writer.content(None) self.writer.content('') self._verify('<robot>\n') def test_element(self): self.writer.element('div', 'content', {'id': '1'}) self.writer.element('i', newline=False) self._verify('<div id="1">content</div>\n<i></i>') def test_line_separator(self): output = StringIO() writer = HtmlWriter(output) writer.start('b') writer.end('b') writer.element('i') assert_equal(output.getvalue(), '<b>\n</b>\n<i></i>\n') def test_non_ascii(self): self.output = StringIO() writer = HtmlWriter(self.output) writer.start(u'p', attrs={'name': u'hyv\xe4\xe4'}, newline=False) writer.content(u'y\xf6') writer.element('i', u't\xe4', newline=False) writer.end('p', newline=False) self._verify(u'<p name="hyv\xe4\xe4">y\xf6<i>t\xe4</i></p>') def _verify(self, expected): assert_equal(self.output.getvalue(), expected)
class TestHtmlWriter(unittest.TestCase): def setUp(self): self.output = StringIO() self.writer = HtmlWriter(self.output) def test_start(self): self.writer.start('r') self._verify('<r>\n') def test_start_without_newline(self): self.writer.start('robot', newline=False) self._verify('<robot>') def test_start_with_attribute(self): self.writer.start('robot', {'name': 'Suite1'}, False) self._verify('<robot name="Suite1">') def test_start_with_attributes(self): self.writer.start('test', {'class': '123', 'x': 'y', 'a': 'z'}) self._verify('<test a="z" class="123" x="y">\n') def test_start_with_non_ascii_attributes(self): self.writer.start('test', {'name': u'\xA7', u'\xE4': u'\xA7'}) self._verify(u'<test name="\xA7" \xE4="\xA7">\n') def test_start_with_quotes_in_attribute_value(self): self.writer.start('x', {'q':'"', 'qs': '""""', 'a': "'"}, False) self._verify('<x a="\'" q=""" qs="""""">') def test_start_with_html_in_attribute_values(self): self.writer.start('x', {'1':'<', '2': '&', '3': '</html>'}, False) self._verify('<x 1="<" 2="&" 3="</html>">') def test_start_with_newlines_and_tabs_in_attribute_values(self): self.writer.start('x', {'1':'\n', '3': 'A\nB\tC', '2': '\t', '4': '\r\n'}, False) self._verify('<x 1=" " 2="	" 3="A B	C" 4=" ">') def test_end(self): self.writer.start('robot', newline=False) self.writer.end('robot') self._verify('<robot></robot>\n') def test_end_without_newline(self): self.writer.start('robot', newline=False) self.writer.end('robot', newline=False) self._verify('<robot></robot>') def test_end_alone(self): self.writer.end('suite', newline=False) self._verify('</suite>') def test_content(self): self.writer.start('robot') self.writer.content('Hello world!') self._verify('<robot>\nHello world!') def test_content_with_non_ascii_data(self): self.writer.start('robot', newline=False) self.writer.content(u'Circle is 360\xB0. ') self.writer.content(u'Hyv\xE4\xE4 \xFC\xF6t\xE4!') self.writer.end('robot', newline=False) expected = u'Circle is 360\xB0. Hyv\xE4\xE4 \xFC\xF6t\xE4!' self._verify('<robot>%s</robot>' % expected) def test_multiple_content(self): self.writer.start('robot') self.writer.content('Hello world!') self.writer.content('Hi again!') self._verify('<robot>\nHello world!Hi again!') def test_content_with_chars_needing_escaping(self): self.writer.content('Me, "Myself" & I > U') self._verify('Me, "Myself" & I > U') def test_content_alone(self): self.writer.content('hello') self._verify('hello') def test_none_content(self): self.writer.start('robot') self.writer.content(None) self.writer.content('') self._verify('<robot>\n') def test_element(self): self.writer.element('div', 'content', {'id': '1'}) self.writer.element('i', newline=False) self._verify('<div id="1">content</div>\n<i></i>') def test_line_separator(self): self._test_line_separator('\n') self._test_line_separator('LINESEP') def _test_line_separator(self, linesep): output = StringIO() writer = HtmlWriter(output, line_separator=linesep) writer.start('b') writer.end('b') writer.element('i') expected = '<b>%(LS)s</b>%(LS)s<i></i>%(LS)s' % {'LS': linesep} assert_equals(repr(output.getvalue()), repr(expected)) def test_encoding(self): self._test_encoding('UTF-8') self._test_encoding('ISO-8859-1') def _test_encoding(self, encoding): self.output = StringIO() writer = HtmlWriter(self.output, encoding=encoding) writer.start(u'p', attrs={'name': u'hyv\xe4\xe4'}, newline=False) writer.content(u'y\xf6') writer.element('i', u't\xe4', newline=False) writer.end('p', newline=False) self._verify(u'<p name="hyv\xe4\xe4">y\xf6<i>t\xe4</i></p>'.encode(encoding)) def _verify(self, expected): actual = self.output.getvalue() if '\n' in expected: expected = expected.replace('\n', os.linesep) assert_equals(actual, expected)
class TestHtmlWriter(unittest.TestCase): def setUp(self): self.out = IOMock() self.writer = HtmlWriter(self.out) def test_encode_without_illegal_char(self): actual = self.writer._escape_content('\\x09') expected = '\\x09' self._verify(expected, actual) def test_init(self): self.writer.start('r') self._verify('<r>\n') def test_start(self): self.writer.start('robot', newline=False) self._verify('<robot>') def test_start_with_attribute(self): self.writer.start('robot', newline=False) self.writer.start('suite', {'name': 'Suite1'}, False) self._verify('<robot><suite name="Suite1">') def test_start_with_attribute2(self): self.writer.start('test case', {'class': '123'}) self._verify('<test case class="123">\n') def test_start_with_attributes(self): self.writer.start('test case', {'class': '123', 'x': 'y'}) self._verify('<test case class="123" x="y">\n') def test_start_with_non_ascii_attributes(self): self.writer.start('test', {'name': u'\u00A7', u'\u00E4': u'\u00A7'}) self._verify(u'<test name="\u00A7" \u00E4="\u00A7">\n') def test_start_with_quotes_in_attribute_value(self): self.writer.start('x', {'q': '"', 'qs': '""""', 'a': "'"}, False) self._verify('<x a="\'" q=""" qs="""""">') def test_start_with_html_in_attribute_values(self): self.writer.start('x', {'1': '<', '2': '&', '3': '</html>'}, False) self._verify('<x 1="<" 2="&" 3="</html>">') def test_start_with_newlines_and_tabs_in_attribute_values(self): self.writer.start('x', {'1': '\n', '3': 'A\nB\tC', '2': '\t'}, False) self._verify('<x 1=" " 2=" " 3="A B C">') def test_end(self): self.writer.start('robot', newline=False) self.writer.end('robot') self._verify('<robot></robot>\n') def test_content(self): self.writer.start('robot') self.writer.content('Hello world!') self._verify('<robot>\nHello world!') def test_content_with_non_ascii_data(self): self.writer.start('robot', newline=False) self.writer.content(u'Circle is 360\u00B0. ') self.writer.content(u'Hyv\u00E4\u00E4 \u00FC\u00F6t\u00E4!') self.writer.end('robot', newline=False) expected = u'Circle is 360\u00B0. Hyv\u00E4\u00E4 \u00FC\u00F6t\u00E4!' self._verify('<robot>%s</robot>' % expected) def test_multiple_content(self): self.writer.start('robot') self.writer.content('Hello world!') self.writer.content('Hi again!') self._verify('<robot>\nHello world!Hi again!') def test_content_with_entities(self): self.writer.start('robot') self.writer.content('Me, Myself & I') self._verify('<robot>\nMe, Myself & I') def test_none_content(self): self.writer.start('robot') self.writer.content(None) self._verify('<robot>\n') def test_content_with_non_strings(self): class NonString: def __nonzero__(self): return False def __str__(self): return 'nonzero' for i in range(10): self.writer.content(i) self.writer.content(NonString()) self._verify('0123456789nonzero') def test_close_empty(self): self.writer.end('suite', False) self._verify('</suite>') def _verify(self, expected, actual=None): if actual == None: actual = self.out.getvalue().decode('UTF-8') assert_equals(expected, actual)