Exemplo n.º 1
0
    def _appendrow(self, result_name, report):
        time = getattr(report, 'duration', 0.0)

        additional_html = []
        links_html = []

        for extra in getattr(report, 'extra', []):
            self.append_extra_html(extra, additional_html, links_html)

        self.append_log_html(report, additional_html)

        test_id = report.nodeid
        if report.when != 'call':
            test_id = '::'.join([report.nodeid, report.when])

        rows_table = html.tr([
            html.td(result_name, class_='col-result'),
            html.td(test_id, class_='col-name'),
            html.td('{0:.2f}'.format(time), class_='col-duration'),
            html.td(links_html, class_='col-links')])

        rows_extra = html.tr(html.td(additional_html,
                             class_='extra', colspan='5'))

        self.test_logs.append(html.tbody(rows_table, rows_extra,
                                         class_=result_name.lower() +
                                         ' results-table-row'))
Exemplo n.º 2
0
        def __init__(self, outcome, report, self_contained, logfile):
            self.test_id = report.nodeid
            if report.when != 'call':
                self.test_id = '::'.join([report.nodeid, report.when])
            self.time = getattr(report, 'duration', 0.0)
            self.outcome = outcome
            self.additional_html = []
            self.links_html = []
            self.self_contained = self_contained
            self.logfile = logfile

            test_index = hasattr(report, 'rerun') and report.rerun + 1 or 0

            for extra_index, extra in enumerate(getattr(report, 'extra', [])):
                self.append_extra_html(extra, extra_index, test_index)

            xfail = hasattr(report, 'wasxfail')
            if (report.skipped and xfail) or (report.failed and not xfail):
                self.append_log_html(report, self.additional_html)

            self.row_table = html.tr([
                html.td(self.outcome, class_='col-result'),
                html.td(self.test_id, class_='col-name'),
                html.td('{0:.2f}'.format(self.time), class_='col-duration'),
                html.td(self.links_html, class_='col-links')
            ])

            self.row_extra = html.tr(
                html.td(self.additional_html, class_='extra', colspan='5'))
Exemplo n.º 3
0
    def insert_data(self, tables_data: dict):
        if not isinstance(tables_data, dict):
            raise TypeError(
                f'{self.__module__} supports only dict as InputParam')

        self.tables_processed = len(tables_data.keys())

        for raw_table_name, raw_table_data in tables_data.items():
            csv_file_path = raw_table_data['Athena']['FilePath']

            database_name, table_name = raw_table_name.split('.')
            self.data_results.append(
                html.div(
                    html.h3(f"Input data: {raw_table_name}"),
                    html.table(
                        html.tr([
                            html.th('Database:', class_='database-name'),
                            html.th(database_name)
                        ]),
                        html.tr([
                            html.th('Table name:', class_='table-name'),
                            html.th(table_name)
                        ]),
                        self._generate_glue_report(raw_table_data['Glue']),
                        self._generate_s3_report(raw_table_data['S3']),
                        self._generate_athena_report(raw_table_data['Athena']),
                        class_="processed-table"),
                    html.div(f"{self._get_csv_data(csv_file_path)}",
                             table_name=table_name,
                             class_="data-tables")))
Exemplo n.º 4
0
        def __init__(self, outcome, report, logfile, config):
            self.test_id = report.nodeid.encode("utf-8").decode(
                "unicode_escape")
            if getattr(report, "when", "call") != "call":
                self.test_id = "::".join([report.nodeid, report.when])
            self.time = getattr(report, "duration", 0.0)
            self.formatted_time = self._format_time(report)
            self.outcome = outcome
            self.additional_html = []
            self.links_html = []
            self.self_contained = config.getoption("self_contained_html")
            self.max_asset_filename_length = int(
                config.getini("max_asset_filename_length"))
            self.logfile = logfile
            self.config = config
            self.row_table = self.row_extra = None

            test_index = hasattr(report, "rerun") and report.rerun + 1 or 0

            for extra_index, extra in enumerate(getattr(report, "extra", [])):
                self.append_extra_html(extra, extra_index, test_index)

            self.append_log_html(
                report,
                self.additional_html,
                config.option.capture,
                config.option.showcapture,
            )

            cells = [
                html.td(self.outcome, class_="col-result"),
                html.td(self.test_id, class_="col-name"),
                html.td(self.formatted_time, class_="col-duration"),
                html.td(self.links_html, class_="col-links"),
            ]

            self.config.hook.pytest_html_results_table_row(report=report,
                                                           cells=cells)

            self.config.hook.pytest_html_results_table_html(
                report=report, data=self.additional_html)

            if len(cells) > 0:
                tr_class = None
                if self.config.getini("render_collapsed"):
                    tr_class = "collapsed"
                self.row_table = html.tr(cells)
                self.row_extra = html.tr(
                    html.td(self.additional_html,
                            class_="extra",
                            colspan=len(cells)),
                    class_=tr_class,
                )
Exemplo n.º 5
0
    def generate_html(self):
        generated = datetime.utcnow()
        with open(os.path.join(base_path, "main.js")) as main_f:
            doc = html.html(
                self.head,
                html.body(
                    html.script(raw(main_f.read())),
                    html.p('Report generated on %s at %s' %
                           (generated.strftime('%d-%b-%Y'),
                            generated.strftime('%H:%M:%S'))),
                    html.h2('Environment'),
                    html.table([
                        html.tr(html.td(k), html.td(v))
                        for k, v in sorted(self.env.items()) if v
                    ],
                               id='environment'), html.h2('Summary'),
                    html.p(
                        '%i tests ran in %.1f seconds.' %
                        (sum(self.test_count.itervalues()),
                         (self.suite_times["end"] - self.suite_times["start"])
                         / 1000.), html.br(),
                        html.span('%i passed' % self.test_count["PASS"],
                                  class_='pass'), ', ',
                        html.span('%i skipped' % self.test_count["SKIP"],
                                  class_='skip'), ', ',
                        html.span('%i failed' %
                                  self.test_count["UNEXPECTED_FAIL"],
                                  class_='fail'), ', ',
                        html.span('%i errors' %
                                  self.test_count["UNEXPECTED_ERROR"],
                                  class_='error'), '.', html.br(),
                        html.span('%i expected failures' %
                                  self.test_count["EXPECTED_FAIL"],
                                  class_='expected_fail'), ', ',
                        html.span('%i unexpected passes' %
                                  self.test_count["UNEXPECTED_PASS"],
                                  class_='unexpected_pass'), '.'),
                    html.h2('Results'),
                    html.table([
                        html.thead(html.tr([
                            html.th('Result', class_='sortable', col='result'),
                            html.th('Test', class_='sortable', col='name'),
                            html.th('Duration',
                                    class_='sortable numeric',
                                    col='duration'),
                            html.th('Links')
                        ]),
                                   id='results-table-head'),
                        html.tbody(self.result_rows, id='results-table-body')
                    ],
                               id='results-table')))

        return u"<!DOCTYPE html>\n" + doc.unicode(indent=2)
Exemplo n.º 6
0
 def gen_html_table(mtx):
     from py.xml import html
     # print("DBG genhtmltable", mtx)
     result = html.table(
         html.thead(html.tr([html.th(x) for x in mtx[0]])),  # header
         html.tbody(*[
             html.tr([html.td(x) for x in row])  # rows
             for row in mtx[1:]
         ]),
         class_="fixed_headers")
     # make it fixed height scrollable # https://codepen.io/tjvantoll/pen/JEKIu
     # result = str(result) + """
     # """
     return str(result)
Exemplo n.º 7
0
 def gen_html_table( mtx ):
     from py.xml import html
     # print("DBG genhtmltable", mtx)
     result  = html.table(
         html.thead( html.tr( [html.th( x ) for x in mtx[0] ] ) ),  # header
         html.tbody( 
                 *[ html.tr( [html.td( x ) for x in row] )   # rows
                     for row in mtx[1:] ] 
                     ),
         class_="fixed_headers"
     ) 
     # make it fixed height scrollable # https://codepen.io/tjvantoll/pen/JEKIu
     # result = str(result) + """
     # """
     return str(result) 
Exemplo n.º 8
0
        def __init__(self, outcome, report, logfile, config):

            #self.test_id = report.nodeid
            self.test_id = (' ::').join(report.nodeid.split('::'))
            if getattr(report, 'when', 'call') != 'call':
                self.test_id = ' ::'.join([report.nodeid, report.when])
            self.time = getattr(report, 'duration', 0.00)
            self.outcome = outcome
            self.additional_html = []
            self.links_html = []
            self.self_contained = config.getoption('self_contained_html')
            self.logfile = logfile
            self.config = config
            self.row_table = self.row_extra = None

            test_index = hasattr(report, 'rerun') and report.rerun + 1 or 0

            for extra_index, extra in enumerate(getattr(report, 'extra', [])):
                self.append_extra_html(extra, extra_index, test_index)

            self.append_log_html(report, self.additional_html)

            #add description
            if hasattr(report, "description"):
                des = report.description
            else:
                des = "无"

            cells = [
                html.td(self.outcome, class_='col-result'),
                html.td(des, class_='col-description'),  #des
                html.td(self.test_id, class_='col-name'),
                html.td('{0:.2f}'.format(self.time), class_='col-duration')
                #,html.td(self.links_html, class_='col-links')
            ]

            self.config.hook.pytest_html_results_table_row(report=report,
                                                           cells=cells)

            self.config.hook.pytest_html_results_table_html(
                report=report, data=self.additional_html)

            if len(cells) > 0:
                self.row_table = html.tr(cells)
                self.row_extra = html.tr(
                    html.td(self.additional_html,
                            class_='extra',
                            colspan=len(cells)))
Exemplo n.º 9
0
    def _generate_environment(self, config):
        if not hasattr(config, "_metadata") or config._metadata is None:
            return []

        metadata = config._metadata
        environment = [html.h2("测试环境")]
        rows = []

        keys = [k for k in metadata.keys()]
        # if not isinstance(metadata, OrderedDict):
        #     keys.sort()

        for key in keys:
            value = metadata[key]
            if isinstance(value, str) and value.startswith("http"):
                value = html.a(value, href=value, target="_blank")
            elif isinstance(value, (list, tuple, set)):
                value = ", ".join(str(i) for i in sorted(map(str, value)))
            elif isinstance(value, dict):
                sorted_dict = {k: value[k] for k in sorted(value)}
                value = json.dumps(sorted_dict)
            raw_value_string = raw(str(value))
            rows.append(html.tr(html.td(TEST_ENV.get(key)), html.td(raw_value_string)))

        environment.append(html.table(rows, id="environment"))
        return environment
Exemplo n.º 10
0
    def _generate_environment(self, config):
        if not hasattr(config, "_metadata") or config._metadata is None:
            return []

        metadata = config._metadata
        if 'Capabilities' in metadata:
            metadata.pop('Capabilities')
        if 'Base URL' in config._metadata:
            metadata.pop('Base URL')
        environment = [html.h2("Environment")]
        rows = []

        keys = [k for k in metadata.keys()]
        if not isinstance(metadata, OrderedDict):
            keys.sort()

        for key in keys:
            value = metadata[key]
            if isinstance(value, str) and value.startswith("http"):
                value = html.a(value, href=value, target="_blank")
            elif isinstance(value, (list, tuple, set)):
                value = ", ".join(str(i) for i in value)
            rows.append(html.tr(html.td(key), html.td(value)))

        environment.append(html.table(rows, id="environment"))
        return environment
Exemplo n.º 11
0
    def _generate_environment(self, environment_details):
        rows = []

        keys = [
            k for k in environment_details.keys() if environment_details[k]
        ]
        if not isinstance(environment_details, OrderedDict):
            keys.sort()

        for key in keys:
            value = environment_details[key]
            if isinstance(value, basestring) and value.startswith("http"):
                value = html.a(value, href=value, target="_blank")
            elif isinstance(value, (list, tuple, set)):
                value = ", ".join((str(i) for i in value))
            rows.append(html.tr(html.td(key), html.td(value)))

        environment = html.div(
            html.h2("Environment"),
            html.div(
                html.table(rows, id="environment"),
                class_="environment-info",
            ),
            class_="environment-details",
        )
        return environment
Exemplo n.º 12
0
    def make_table_rows(self):
        regressions = self.results.regressions

        rv = []
        tests = sorted(regressions.keys())
        for i, test in enumerate(tests):
            test_data = regressions[test]
            cells, needs_subtest = self.make_test_name(test, test_data, i)
            for subtest in sorted(test_data.keys()):
                if needs_subtest:
                    cells.append(html.td(subtest))
                subtest_data = test_data[subtest]
                cells.extend([
                    html.td(subtest_data["expected"].title(),
                            class_="condition %s" % subtest_data["expected"]),
                    html.td(subtest_data["status"].title(),
                            class_="condition %s" % subtest_data["status"]),
                    html.td(subtest_data.get("message", ""),
                            class_="message")
                ])
                tr = html.tr(cells)
                rv.append(tr)
                cells = []
                needs_subtest = True
        return rv
Exemplo n.º 13
0
    def _generate_environment(self, config):
        if not hasattr(config, "_metadata") or config._metadata is None:
            return []

        metadata = config._metadata
        environment = [html.h2("Environment")]
        rows = []

        keys = [k for k in metadata.keys()]
        if not isinstance(metadata, OrderedDict):
            keys.sort()

        for key in keys:
            value = metadata[key]
            if isinstance(value, str) and value.startswith("http"):
                value = html.a(value, href=value, target="_blank")
            elif isinstance(value, (list, tuple, set)):
                value = ", ".join(str(i) for i in sorted(map(str, value)))
            elif isinstance(value, dict):
                key_value_list = [f"'{k}': {value[k]}" for k in sorted(value)]
                value = ", ".join(key_value_list)
                value = "{" + value + "}"
            raw_value_string = raw(str(value))
            rows.append(html.tr(html.td(key), html.td(raw_value_string)))

        environment.append(html.table(rows, id="environment"))
        return environment
Exemplo n.º 14
0
    def version_get(self, user, index, name, version):
        stage = self.getstage(user, index)
        name = ensure_unicode(name)
        version = ensure_unicode(version)
        metadata = stage.get_projectconfig(name)
        if not metadata:
            abort(404, "project %r does not exist" % name)
        verdata = metadata.get(version, None)
        if not verdata:
            abort(404, "version %r does not exist" % version)
        if json_preferred():
            apireturn(200, type="versiondata", result=verdata)

        # if html show description and metadata
        rows = []
        for key, value in sorted(verdata.items()):
            if key == "description":
                continue
            if isinstance(value, list):
                value = html.ul([html.li(x) for x in value])
            rows.append(html.tr(html.td(key), html.td(value)))
        title = "%s/: %s-%s metadata and description" % (stage.name, name,
                                                         version)

        content = stage.get_description(name, version)
        #css = "https://pypi.python.org/styles/styles.css"
        return simple_html_body(
            title, [html.table(*rows), py.xml.raw(content)],
            extrahead=[
                html.link(media="screen",
                          type="text/css",
                          rel="stylesheet",
                          title="text",
                          href="https://pypi.python.org/styles/styles.css")
            ]).unicode(indent=2)
Exemplo n.º 15
0
    def version_get(self, user, index, name, version):
        stage = self.getstage(user, index)
        name = ensure_unicode(name)
        version = ensure_unicode(version)
        metadata = stage.get_projectconfig(name)
        if not metadata:
            abort(404, "project %r does not exist" % name)
        verdata = metadata.get(version, None)
        if not verdata:
            abort(404, "version %r does not exist" % version)
        if json_preferred():
            apireturn(200, type="versiondata", result=verdata)

        # if html show description and metadata
        rows = []
        for key, value in sorted(verdata.items()):
            if key == "description":
                continue
            if isinstance(value, list):
                value = html.ul([html.li(x) for x in value])
            rows.append(html.tr(html.td(key), html.td(value)))
        title = "%s/: %s-%s metadata and description" % (
                stage.name, name, version)

        content = stage.get_description(name, version)
        #css = "https://pypi.python.org/styles/styles.css"
        return simple_html_body(title,
            [html.table(*rows), py.xml.raw(content)],
            extrahead=
            [html.link(media="screen", type="text/css",
                rel="stylesheet", title="text",
                href="https://pypi.python.org/styles/styles.css")]
        ).unicode(indent=2)
Exemplo n.º 16
0
    def make_table_rows(self, results):
        rv = []
        for result in results:
            details_link = "%s/report.html" % result.name
            cells = [html.td(result.name)]
            if result.has_errors:
                cells.append(html.td(
                    len(result.errors),
                    class_="condition FAIL",
                ))
            else:
                cells.append(html.td("0",
                                     class_="condition PASS"))
            if result.has_regressions:
                num_regressions = sum(len(item) for item in result.regressions.itervalues())
                cells.append(html.td(num_regressions, class_="condition FAIL"))
            else:
                cells.append(html.td("0", class_="condition PASS"))

            if result.is_pass:
                cells.append(html.td())
            else:
                cells.append(html.td(
                    html.a("details",
                           href=details_link),
                    class_="details"
                ))
            rv.append(html.tr(cells))

        return rv
Exemplo n.º 17
0
 def add_row(self, lineno, text):
     if text == ['']:
         text = [raw('&#xa0;')]
     else:
         text = prepare_line(text, self.tokenizer, self.encoding)
     self.tbody.append(html.tr(html.td(str(lineno), class_='lineno'),
                               html.td(class_='code', *text)))
Exemplo n.º 18
0
    def generate_html(self):
        generated = datetime.datetime.now()
        with open(os.path.join(base_path, "main.js")) as main_f:
            doc = html.html(
                self.head,
                html.body(
                    html.script(raw(main_f.read())),
                    html.p(
                        "Report generated on %s at %s"
                        % (generated.strftime("%d-%b-%Y"), generated.strftime("%H:%M:%S")),
                        html.h2("Summary"),
                        html.p(
                            "%i tests ran in %.1f seconds."
                            % (
                                sum(self.test_count.itervalues()),
                                (self.suite_times["end"] - self.suite_times["start"]) / 1000.0,
                            ),
                            html.br(),
                            html.span("%i passed" % self.test_count["PASS"], class_="pass"),
                            ", ",
                            html.span("%i skipped" % self.test_count["SKIP"], class_="skip"),
                            ", ",
                            html.span("%i failed" % self.test_count["UNEXPECTED_FAIL"], class_="fail"),
                            ", ",
                            html.span("%i errors" % self.test_count["UNEXPECTED_ERROR"], class_="error"),
                            ".",
                            html.br(),
                            html.span(
                                "%i expected failures" % self.test_count["EXPECTED_FAIL"], class_="expected_fail"
                            ),
                            ", ",
                            html.span(
                                "%i unexpected passes" % self.test_count["UNEXPECTED_PASS"], class_="unexpected_pass"
                            ),
                            ".",
                        ),
                        html.h2("Results"),
                        html.table(
                            [
                                html.thead(
                                    html.tr(
                                        [
                                            html.th("Result", class_="sortable", col="result"),
                                            html.th("Class", class_="sortable", col="class"),
                                            html.th("Test Name", class_="sortable", col="name"),
                                            html.th("Duration", class_="sortable numeric", col="duration"),
                                            html.th("Links"),
                                        ]
                                    ),
                                    id="results-table-head",
                                ),
                                html.tbody(self.result_rows, id="results-table-body"),
                            ],
                            id="results-table",
                        ),
                    ),
                ),
            )

        return u"<!DOCTYPE html>\n" + doc.unicode(indent=2)
Exemplo n.º 19
0
    def _appendrow(self, result, report):
        time = getattr(report, 'duration', 0.0)

        additional_html = []
        links_html = []

        for extra in getattr(report, 'extra', []):
            href = None
            if extra.get('format') == extras.FORMAT_IMAGE:
                href = '#'
                image = 'data:image/png;base64,%s' % extra.get('content')
                additional_html.append(html.div(
                    html.a(html.img(src=image), href="#"),
                    class_='image'))
            elif extra.get('format') == extras.FORMAT_HTML:
                additional_html.append(extra.get('content'))
            elif extra.get('format') == extras.FORMAT_JSON:
                href = data_uri(json.dumps(extra.get('content')),
                                mime_type='application/json')
            elif extra.get('format') == extras.FORMAT_TEXT:
                href = data_uri(extra.get('content'))
            elif extra.get('format') == extras.FORMAT_URL:
                href = extra.get('content')

            if href is not None:
                links_html.append(html.a(
                    extra.get('name'),
                    class_=extra.get('format'),
                    href=href,
                    target='_blank'))
                links_html.append(' ')

        if 'Passed' not in result:

            if report.longrepr:
                log = html.div(class_='log')
                for line in str(report.longrepr).splitlines():
                    if not PY3:
                        line = line.decode('utf-8')
                    separator = line.startswith('_ ' * 10)
                    if separator:
                        log.append(line[:80])
                    else:
                        exception = line.startswith("E   ")
                        if exception:
                            log.append(html.span(raw(escape(line)),
                                                 class_='error'))
                        else:
                            log.append(raw(escape(line)))
                    log.append(html.br())
                additional_html.append(log)

        self.test_logs.append(html.tr([
            html.td(result, class_='col-result'),
            html.td(report.nodeid, class_='col-name'),
            html.td('%.2f' % time, class_='col-duration'),
            html.td(links_html, class_='col-links'),
            html.td(additional_html, class_='extra')],
            class_=result.lower() + ' results-table-row'))
Exemplo n.º 20
0
    def make_result_html(self, data):
        tc_time = (data["time"] - self.start_times.pop(data["test"])) / 1000.
        additional_html = []
        debug = data.get("extra", {})
        links_html = []

        status = status_name = data["status"]
        expected = data.get("expected", status)

        if status != expected:
            status_name = "UNEXPECTED_" + status
        elif status != "PASS":
            status_name = "EXPECTED_" + status

        self.test_count[status_name] += 1

        if status in ['SKIP', 'FAIL', 'ERROR']:
            if debug.get('screenshot'):
                screenshot = 'data:image/png;base64,%s' % debug['screenshot']
                additional_html.append(html.div(
                    html.a(html.img(src=screenshot), href="#"),
                    class_='screenshot'))
            for name, content in debug.items():
                if 'screenshot' in name:
                    href = '#'
                else:
                    # use base64 to avoid that some browser (such as Firefox, Opera)
                    # treats '#' as the start of another link if the data URL contains.
                    # use 'charset=utf-8' to show special characters like Chinese.
                    href = 'data:text/plain;charset=utf-8;base64,%s' % base64.b64encode(content.encode('utf-8'))
                links_html.append(html.a(
                    name.title(),
                    class_=name,
                    href=href,
                    target='_blank'))
                links_html.append(' ')

            log = html.div(class_='log')
            output = data.get('stack', '').splitlines()
            output.extend(data.get('message', '').splitlines())
            for line in output:
                separator = line.startswith(' ' * 10)
                if separator:
                    log.append(line[:80])
                else:
                    if line.lower().find("error") != -1 or line.lower().find("exception") != -1:
                        log.append(html.span(raw(cgi.escape(line)), class_='error'))
                    else:
                        log.append(raw(cgi.escape(line)))
                log.append(html.br())
            additional_html.append(log)

        self.result_rows.append(
            html.tr([html.td(status_name, class_='col-result'),
                     html.td(data['test'], class_='col-name'),
                     html.td('%.2f' % tc_time, class_='col-duration'),
                     html.td(links_html, class_='col-links'),
                     html.td(additional_html, class_='debug')],
                    class_=status_name.lower() + ' results-table-row'))
Exemplo n.º 21
0
 def html_table_row(self):
     cells = html.tr([
         html.td(v, class_=class_)
         for v, class_ in zip(self.formatted_statistics, COLUMN_CLASSES)
     ])
     self.config.hook.pytest_aggreport_html_table_row(result=self,
                                                      cells=cells)
     return cells
Exemplo n.º 22
0
 def make_errors_table(self, errors):
     rows = []
     for error in errors:
         rows.append(html.tr(
             html.td(error["level"],
                     class_="log_%s" % error["level"]),
             html.td(error.get("message", ""))
         ))
     return html.table(rows, id_="errors")
Exemplo n.º 23
0
 def make_result_table(self):
     return html.table(html.thead(
         html.tr(html.th("Subsuite", class_='sortable', col='subsuite'),
                 html.th("Subsuite Errors"), html.th("Test Executions"),
                 html.th("Details"))),
                       html.tbody(self.make_table_rows(
                           self.subsuite_results),
                                  id='results-table-body'),
                       id='results-table')
Exemplo n.º 24
0
    def _appendrow(self, result, report):
        time = getattr(report, 'duration', 0.0)

        additional_html = []
        links_html = []

        if 'Passed' not in result:

            for extra in getattr(report, 'extra', []):
                href = None
                if type(extra) is Image:
                    href = '#'
                    image = 'data:image/png;base64,%s' % extra.content
                    additional_html.append(html.div(
                        html.a(html.img(src=image), href="#"),
                        class_='image'))
                elif type(extra) is HTML:
                    additional_html.append(extra.content)
                elif type(extra) is Text:
                    href = 'data:text/plain;charset=utf-8;base64,%s' % \
                        b64encode(extra.content)
                elif type(extra) is URL:
                    href = extra.content

                if href is not None:
                    links_html.append(html.a(
                        extra.name,
                        class_=extra.__class__.__name__.lower(),
                        href=href,
                        target='_blank'))
                    links_html.append(' ')

            if report.longrepr:
                log = html.div(class_='log')
                for line in str(report.longrepr).splitlines():
                    line = line.decode('utf-8')
                    separator = line.startswith('_ ' * 10)
                    if separator:
                        log.append(line[:80])
                    else:
                        exception = line.startswith("E   ")
                        if exception:
                            log.append(html.span(raw(cgi.escape(line)),
                                                 class_='error'))
                        else:
                            log.append(raw(cgi.escape(line)))
                    log.append(html.br())
                additional_html.append(log)

        self.test_logs.append(html.tr([
            html.td(result, class_='col-result'),
            html.td(report.nodeid, class_='col-name'),
            html.td('%.2f' % time, class_='col-duration'),
            html.td(links_html, class_='col-links'),
            html.td(additional_html, class_='extra')],
            class_=result.lower() + ' results-table-row'))
Exemplo n.º 25
0
    def _create_overview(self):
        for node, results in self.tempDict.iteritems():
            table = [html.td(node, class_="col-name")]

            res = [
                html.td(result.capitalize(), class_="%s col-%s" % (result.lower(), when))
                for when, result in results.iteritems()
            ]
            table.extend(res)
            self.test_overview.append(html.tr(table))
Exemplo n.º 26
0
    def make_body(self):
        body_parts = [
            html.div(
                html.script(raw(
                    pkg_resources.resource_string(
                        rcname,
                        os.path.sep.join(
                            ['resources', 'htmlreport', 'jquery.js']))),
                            type='text/javascript'),
                html.script(raw(
                    pkg_resources.resource_string(
                        rcname,
                        os.path.sep.join(
                            ['resources', 'htmlreport', 'main.js']))),
                            type='text/javascript'),
                html.h1("FirefoxOS Certification Suite Report"),
                html.p("Run at %s" % self.time.strftime("%Y-%m-%d %H:%M:%S")))
        ]
        if self.logs:
            device_profile_object = None
            with open(self.logs[-1]) as f:
                device_profile_object = json.load(f)['result']['contact']
            device_profile = [html.h2('Device Information')]
            device_table = html.table()
            for key in device_profile_object:
                device_table.append(
                    html.tr(html.td(key), html.td(device_profile_object[key])))
                #device_profile.append(html.p("%s, %s"% (key, device_profile_object[key])))
            device_profile.append(device_table)
            body_parts.extend(device_profile)

        if self.summary_results.has_errors:
            body_parts.append(html.h2("Errors During Run"))
            body_parts.append(
                self.make_errors_table(self.summary_results.errors))
        body_parts.append(html.h2("Test Results"))
        body_parts.append(self.make_result_table())

        if self.logs:
            ulbody = []
            for log_path in self.logs:
                details_log = ''
                with open(log_path, 'r') as f:
                    details_log = f.read()
                href = 'data:text/plain;charset=utf-8;base64,%s' % base64.b64encode(
                    details_log)
                ulbody.append(
                    html.li(
                        html.a(os.path.basename(log_path),
                               href=href,
                               target='_blank')))
            device_profile_object = None
            body_parts.append(html.h2("Details log information"))
            body_parts.append(html.ul(ulbody))
        return html.body(body_parts)
Exemplo n.º 27
0
 def make_regression_table(self):
     return html.table(html.thead(html.tr(
         html.th("Parent Test", col='parent'),
         html.th("Subtest", col='subtest'),
         html.th("Expected", col='expected'),
         html.th("Result", col='result'),
     ),
                                  id='results-table-head'),
                       html.tbody(*self.make_table_rows(),
                                  id='results-table-body'),
                       id='results-table')
Exemplo n.º 28
0
def pytest_html_results_summary(prefix, summary, postfix):
    postfix.extend([HTMLStyle.table(
        html.thead(
            html.tr([
                HTMLStyle.th("Tests"),
                HTMLStyle.th("Success"),
                HTMLStyle.th("Failed"),
                HTMLStyle.th("XFail"),
                HTMLStyle.th("Error")]
            ),
        ),
        [html.tbody(
            html.tr([
                HTMLStyle.td(k),
                HTMLStyle.td(v['passed']),
                HTMLStyle.td(v['failed']),
                HTMLStyle.td(v['xfailed']),
                HTMLStyle.td(v['error']),
            ])
        ) for k, v in results.items()])])
Exemplo n.º 29
0
 def tabelize(value):
     try:
         rows = []
         for key in value.keys():
             rows.append(html.tr(html.td(html.pre(key)), html.td(tabelize(value[key]))))
         return html.table(rows)
     except AttributeError:
         if type(value) == type([]):
             return html.table(map(tabelize, value))
         else:
             return html.pre(value)
Exemplo n.º 30
0
        def _extract_html(test, class_name, duration=0, text='', result='passed', debug=None):
            cls_name = class_name
            tc_name = unicode(test)
            tc_time = duration
            additional_html = []
            debug = debug or {}
            links_html = []

            if result in ['skipped', 'failure', 'expected failure', 'error']:
                if debug.get('screenshot'):
                    screenshot = 'data:image/png;base64,%s' % debug['screenshot']
                    additional_html.append(html.div(
                        html.a(html.img(src=screenshot), href="#"),
                        class_='screenshot'))
                for name, content in debug.items():
                    try:
                        if 'screenshot' in name:
                            href = '#'
                        else:
                            # use base64 to avoid that some browser (such as Firefox, Opera)
                            # treats '#' as the start of another link if the data URL contains.
                            # use 'charset=utf-8' to show special characters like Chinese.
                            href = 'data:text/plain;charset=utf-8;base64,%s' % base64.b64encode(content)
                        links_html.append(html.a(
                            name.title(),
                            class_=name,
                            href=href,
                            target='_blank'))
                        links_html.append(' ')
                    except:
                        pass

                log = html.div(class_='log')
                for line in text.splitlines():
                    separator = line.startswith(' ' * 10)
                    if separator:
                        log.append(line[:80])
                    else:
                        if line.lower().find("error") != -1 or line.lower().find("exception") != -1:
                            log.append(html.span(raw(cgi.escape(line)), class_='error'))
                        else:
                            log.append(raw(cgi.escape(line)))
                    log.append(html.br())
                additional_html.append(log)

            test_logs.append(html.tr([
                html.td(result.title(), class_='col-result'),
                html.td(cls_name, class_='col-class'),
                html.td(tc_name, class_='col-name'),
                html.td(tc_time, class_='col-duration'),
                html.td(links_html, class_='col-links'),
                html.td(additional_html, class_='debug')],
                class_=result.lower() + ' results-table-row'))
Exemplo n.º 31
0
        def _extract_html(test, class_name, duration=0, text='', result='passed', debug=None):
            cls_name = class_name
            tc_name = unicode(test)
            tc_time = duration
            additional_html = []
            debug = debug or {}
            links_html = []

            if result in ['skipped', 'failure', 'expected failure', 'error']:
                if debug.get('screenshot'):
                    screenshot = 'data:image/png;base64,%s' % debug['screenshot']
                    additional_html.append(html.div(
                        html.a(html.img(src=screenshot), href="#"),
                        class_='screenshot'))
                for name, content in debug.items():
                    try:
                        if 'screenshot' in name:
                            href = '#'
                        else:
                            # use base64 to avoid that some browser (such as Firefox, Opera)
                            # treats '#' as the start of another link if the data URL contains.
                            # use 'charset=utf-8' to show special characters like Chinese.
                            href = 'data:text/plain;charset=utf-8;base64,%s' % base64.b64encode(content)
                        links_html.append(html.a(
                            name.title(),
                            class_=name,
                            href=href,
                            target='_blank'))
                        links_html.append(' ')
                    except:
                        pass

                log = html.div(class_='log')
                for line in text.splitlines():
                    separator = line.startswith(' ' * 10)
                    if separator:
                        log.append(line[:80])
                    else:
                        if line.lower().find("error") != -1 or line.lower().find("exception") != -1:
                            log.append(html.span(raw(cgi.escape(line)), class_='error'))
                        else:
                            log.append(raw(cgi.escape(line)))
                    log.append(html.br())
                additional_html.append(log)

            test_logs.append(html.tr([
                html.td(result.title(), class_='col-result'),
                html.td(cls_name, class_='col-class'),
                html.td(tc_name, class_='col-name'),
                html.td(tc_time, class_='col-duration'),
                html.td(links_html, class_='col-links'),
                html.td(additional_html, class_='debug')],
                class_=result.lower() + ' results-table-row'))
Exemplo n.º 32
0
        def __init__(self, outcome, report, logfile, config):
            # self.test_id = report.nodeid.encode("utf-8").decode("unicode_escape")
            self.test_id = report.nodeid
            if getattr(report, "when", "call") != "call":
                self.test_id = "::".join([report.nodeid, report.when])
            self.time = getattr(report, "duration", 0.0)
            self.outcome = outcome
            self.additional_html = []
            self.links_html = []
            self.self_contained = config.getoption("self_contained_html")
            self.logfile = logfile
            self.config = config
            self.row_table = self.row_extra = None

            test_index = hasattr(report, "rerun") and report.rerun + 1 or 0

            for extra_index, extra in enumerate(getattr(report, "extra", [])):
                self.append_extra_html(extra, extra_index, test_index)

            self.append_log_html(report, self.additional_html)

            cells = [
                html.td(self.outcome, class_="col-result"),
                html.td(self.test_id, class_="col-name"),
                html.td(f"{self.time:.2f}", class_="col-duration"),
                html.td(self.links_html, class_="col-links"),
            ]

            self.config.hook.pytest_html_results_table_row(report=report,
                                                           cells=cells)

            self.config.hook.pytest_html_results_table_html(
                report=report, data=self.additional_html)

            if len(cells) > 0:
                self.row_table = html.tr(cells)
                self.row_extra = html.tr(
                    html.td(self.additional_html,
                            class_="extra",
                            colspan=len(cells)))
Exemplo n.º 33
0
        def _extract_html(test, class_name, duration=0, text="", result="passed", debug=None):
            cls_name = class_name
            tc_name = unicode(test)
            tc_time = duration
            additional_html = []
            debug = debug or {}
            links_html = []

            if result in ["skipped", "failure", "expected failure", "error"]:
                if debug.get("screenshot"):
                    screenshot = "data:image/png;base64,%s" % debug["screenshot"]
                    additional_html.append(html.div(html.a(html.img(src=screenshot), href="#"), class_="screenshot"))
                for name, content in debug.items():
                    try:
                        if "screenshot" in name:
                            href = "#"
                        else:
                            # use base64 to avoid that some browser (such as Firefox, Opera)
                            # treats '#' as the start of another link if the data URL contains.
                            # use 'charset=utf-8' to show special characters like Chinese.
                            href = "data:text/plain;charset=utf-8;base64,%s" % base64.b64encode(content)
                        links_html.append(html.a(name.title(), class_=name, href=href, target="_blank"))
                        links_html.append(" ")
                    except:
                        pass

                log = html.div(class_="log")
                for line in text.splitlines():
                    separator = line.startswith(" " * 10)
                    if separator:
                        log.append(line[:80])
                    else:
                        if line.lower().find("error") != -1 or line.lower().find("exception") != -1:
                            log.append(html.span(raw(cgi.escape(line)), class_="error"))
                        else:
                            log.append(raw(cgi.escape(line)))
                    log.append(html.br())
                additional_html.append(log)

            test_logs.append(
                html.tr(
                    [
                        html.td(result.title(), class_="col-result"),
                        html.td(cls_name, class_="col-class"),
                        html.td(tc_name, class_="col-name"),
                        html.td(tc_time, class_="col-duration"),
                        html.td(links_html, class_="col-links"),
                        html.td(additional_html, class_="debug"),
                    ],
                    class_=result.lower() + " results-table-row",
                )
            )
Exemplo n.º 34
0
 def tabelize(value):
     try:
         rows = []
         for key in value.keys():
             rows.append(
                 html.tr(html.td(html.pre(key)),
                         html.td(tabelize(value[key]))))
         return html.table(rows)
     except AttributeError:
         if type(value) == type([]):
             return html.table(map(tabelize, value))
         else:
             return html.pre(value)
Exemplo n.º 35
0
    def generate_html(self):
        generated = datetime.utcnow()
        with open(os.path.join(base_path, "main.js")) as main_f:
            doc = html.html(
                self.head,
                html.body(
                    html.script(raw(main_f.read())),
                    html.p('Report generated on %s at %s' % (
                        generated.strftime('%d-%b-%Y'),
                        generated.strftime('%H:%M:%S'))),
                    html.h2('Environment'),
                    html.table(
                        [html.tr(html.td(k), html.td(v)) for k, v in sorted(self.env.items()) if v],
                        id='environment'),

                    html.h2('Summary'),
                    html.p('%i tests ran in %.1f seconds.' % (sum(self.test_count.itervalues()),
                                                              (self.suite_times["end"] -
                                                               self.suite_times["start"]) / 1000.),
                           html.br(),
                           html.span('%i passed' % self.test_count["PASS"], class_='pass'), ', ',
                           html.span('%i skipped' % self.test_count["SKIP"], class_='skip'), ', ',
                           html.span('%i failed' % self.test_count["UNEXPECTED_FAIL"], class_='fail'), ', ',
                           html.span('%i errors' % self.test_count["UNEXPECTED_ERROR"], class_='error'), '.',
                           html.br(),
                           html.span('%i expected failures' % self.test_count["EXPECTED_FAIL"],
                                     class_='expected_fail'), ', ',
                           html.span('%i unexpected passes' % self.test_count["UNEXPECTED_PASS"],
                                     class_='unexpected_pass'), '.'),
                    html.h2('Results'),
                    html.table([html.thead(
                        html.tr([
                            html.th('Result', class_='sortable', col='result'),
                            html.th('Test', class_='sortable', col='name'),
                            html.th('Duration', class_='sortable numeric', col='duration'),
                            html.th('Links')]), id='results-table-head'),
                        html.tbody(self.result_rows, id='results-table-body')], id='results-table')))

        return u"<!DOCTYPE html>\n" + doc.unicode(indent=2)
Exemplo n.º 36
0
 def make_regression_table(self):
     return html.table(
         html.thead(
             html.tr(
                 html.th("Parent Test", col='parent'),
                 html.th("Subtest", col='subtest'),
                 html.th("Expected", col='expected'),
                 html.th("Result", col='result'),
             ), id='results-table-head'
         ),
         html.tbody(*self.make_table_rows(), id='results-table-body'),
         id='results-table'
     )
Exemplo n.º 37
0
    def _appendrow(self, result, report):
        names = mangle_testnames(report.nodeid.split("::"))
        testclass = (names[:-1])
        if self.prefix:
            testclass.insert(0, self.prefix)
        testclass = ".".join(testclass)
        testmethod = names[-1]
        time = getattr(report, 'duration', 0.0)

        additional_html = []

        if not 'Passed' in result:
            if report.longrepr:
                log = html.div(class_='log')
                for line in str(report.longrepr).splitlines():
                    line = line.decode('utf8')
                    separator = line.startswith('_ ' * 10)
                    if separator:
                        log.append(line[:80])
                    else:
                        exception = line.startswith("E   ")
                        if exception:
                            log.append(
                                html.span(raw(cgi.escape(line)),
                                          class_='error'))
                        else:
                            log.append(raw(cgi.escape(line)))
                    log.append(html.br())
                if not os.path.exists(self.screenshot_path):
                    os.makedirs(self.screenshot_path)
                self.append_screenshot(testmethod, log)
                additional_html.append(log)
        output = self._write_captured_output(report)
        info = output.split(" ")
        links_html = []
        for i in range(0, len(info)):
            if ("http" in info[i] and "browserstack.com" in info[i]):
                links_html.append(html.a("link", href=info[i],
                                         target='_blank'))
                links_html.append(' ')

        self.test_logs.append(
            html.tr([
                html.td(result, class_='col-result'),
                html.td(testclass, class_='col-class'),
                html.td(testmethod, class_='col-name'),
                html.td(round(time), class_='col-duration'),
                html.td(links_html, class_='col-links'),
                html.td(additional_html, class_='debug')
            ],
                    class_=result.lower() + ' results-table-row'))
Exemplo n.º 38
0
 def make_result_table(self):
     return html.table(
         html.thead(
             html.tr(
                 html.th("Subsuite"),
                 html.th("Subsuite Errors"),
                 html.th("Test Regressions"),
                 html.th("Details")
             )
         ),
         html.tbody(
             self.make_table_rows(self.subsuite_results)
         )
     )
Exemplo n.º 39
0
    def pytest_sessionfinish(self, session, exitstatus):
        self._make_report_dir()
        logfile = py.std.codecs.open(self.logfile, 'w', encoding='utf-8')

        suite_stop_time = time.time()
        suite_time_delta = suite_stop_time - self.suite_start_time
        numtests = self.passed + self.failed
        generated = datetime.datetime.now()
        doc = html.html(
            html.head(
                html.meta(charset='utf-8'),
                html.title('Test Report'),
                html.link(rel='stylesheet', href='style.css'),
                html.script(src='jquery.js'),
                html.script(src='main.js')),

            html.body(
                html.p('Report generated on %s at %s ' % (
                    generated.strftime('%d-%b-%Y'),
                    generated.strftime('%H:%M:%S'),
                )),
                html.div([html.p(
                    html.span('%i tests' % numtests, class_='all clickable'),
                    ' ran in %i seconds.' % suite_time_delta,
                    html.br(),
                    html.span('%i passed' % self.passed, class_='passed clickable'), ', ',
                    html.span('%i skipped' % self.skipped, class_='skipped clickable'), ', ',
                    html.span('%i failed' % self.failed, class_='failed clickable'), ', ',
                    html.span('%i errors' % self.errors, class_='error clickable'), '.',
                    html.br(), ),
                    html.span('Hide all errors', class_='clickable hide_all_errors'), ', ',
                    html.span('Show all errors', class_='clickable show_all_errors'),
                ], id='summary-wrapper'),
                html.div(id='summary-space'),
                html.table([
                    html.thead(html.tr([
                        html.th('Result', class_='sortable', col='result'),
                        html.th('Class', class_='sortable', col='class'),
                        html.th('Name', class_='sortable', col='name'),
                        html.th('Duration', class_='sortable numeric', col='duration'),
                        # html.th('Output')]), id='results-table-head'),
                        html.th('Links')]), id='results-table-head'),
                    html.tbody(*self.test_logs, id='results-table-body')], id='results-table')))
        logfile.write(
            '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' + doc.unicode(
                indent=2))
        logfile.close()
        self.process_screenshot_files()
        self.process_debug_event_files()
        self.process_performance_files()
Exemplo n.º 40
0
        def __init__(self, outcome, report, logfile, config):
            self.test_id = report.nodeid
            if getattr(report, 'when', 'call') != 'call':
                self.test_id = '::'.join([report.nodeid, report.when])
            self.time = getattr(report, 'duration', 0.0)
            self.outcome = outcome
            self.additional_html = []
            self.links_html = []
            self.self_contained = config.getoption('self_contained_html')
            self.logfile = logfile
            self.config = config
            self.row_table = self.row_extra = None

            test_index = hasattr(report, 'rerun') and report.rerun + 1 or 0

            for extra_index, extra in enumerate(getattr(report, 'extra', [])):
                self.append_extra_html(extra, extra_index, test_index)

            self.append_log_html(report, self.additional_html)

            cells = [
                html.td(self.outcome, class_='col-result'),
                html.td(self.test_id, class_='col-name'),
                html.td('{0:.2f}'.format(self.time), class_='col-duration'),
                html.td(self.links_html, class_='col-links')]

            self.config.hook.pytest_html_results_table_row(
                report=report, cells=cells)

            self.config.hook.pytest_html_results_table_html(
                report=report, data=self.additional_html)

            if len(cells) > 0:
                self.row_table = html.tr(cells)
                self.row_extra = html.tr(html.td(self.additional_html,
                                                 class_='extra',
                                                 colspan=len(cells)))
Exemplo n.º 41
0
 def _generate_s3_report(s3_data: dict):
     s3_link = s3_data['S3Link']
     s3_data.pop('S3Link')
     file_results = [
         html.p(item) for item in s3_data['FileResults']
         if not item.endswith('/')
     ]
     s3_report = html.tr([
         html.th(f'S3 results:', class_='s3-results'),
         html.th(
             *file_results,
             html.p(html.a(s3_link, href=s3_link)),
         )
     ])
     return s3_report
Exemplo n.º 42
0
 def make_result_table(self):
     return html.table(
         html.thead(
             html.tr(
                 html.th("Subsuite", class_='sortable', col='subsuite'),
                 html.th("Subsuite Errors"),
                 html.th("Test Executions"),
                 html.th("Details")
             )
         ),
         html.tbody(
             self.make_table_rows(self.subsuite_results),id='results-table-body'
         ), 
         id='results-table'
     )
Exemplo n.º 43
0
 def make_regression_table(self):
     return html.table(
         html.thead(
             html.tr(
                 html.th("Parent Test"),
                 html.th("Subtest"),
                 html.th("Expected"),
                 html.th("Result"),
                 html.th("Message")
             )
         ),
         html.tbody(
             *self.make_table_rows()
         )
     )
Exemplo n.º 44
0
 def html_summary_table(self):
     cells = [
         html.th(header,
                 class_=header_class) for header, header_class in zip(
                     COLUMN_HEADERS, COLUMN_HEADER_CLASSES)
     ]
     self.config.hook.pytest_aggreport_html_table_header(cells=cells)
     tbody = [
         html.tr(cells, id='aggregate-report-header'),
     ]
     for case_report in self.case_reports.values():
         tbody.append(case_report.html_table_row)
     html_report = html.table(html.tbody(tbody),
                              id='aggregate-report-table')
     return html_report
Exemplo n.º 45
0
 def handle_dcmp(self, dcmp):
     self.div_container.append(
         html.h2('Diff between %s and %s' % (dcmp.left, dcmp.right)))
     if len(dcmp.left_only) == 0 and len(dcmp.right_only) == 0 and len(
             dcmp.diff_files) == 0:
         self.div_container.append(html.p('No Differences Found'))
     # handle left dir1
     if len(dcmp.left_only) > 0:
         self.div_container.append(html.h3('Only in %s' % (dcmp.left, )))
         ul_left = html.ul()
         for name in dcmp.left_only:
             ul_left.append(html.li(name))
         self.div_container.append(ul_left)
     # handle right dir2
     if len(dcmp.right_only) > 0:
         self.div_container.append(html.h3('Only in %s' % (dcmp.right, )))
         ul_right = html.ul()
         for name in dcmp.right_only:
             ul_right.append(html.li(name))
         self.div_container.append(ul_right)
     # handle diff between dir1 and dir2
     for name in dcmp.diff_files:
         if self.is_binary_file(os.path.join(dcmp.left, name), 1024):
             self.div_container.append(
                 html.table(html.thead(
                     html.tr(html.th(os.path.join(dcmp.left, name)),
                             html.th(os.path.join(dcmp.right, name)))),
                            html.tbody(
                                html.tr(html.td('Binary files differ'))),
                            class_='table'))
         else:
             self.diff_file(os.path.join(dcmp.left, name),
                            os.path.join(dcmp.right, name))
     # handle sub-dirs
     for sub_dcmp in dcmp.subdirs.values():
         self.handle_dcmp(sub_dcmp)
Exemplo n.º 46
0
        def _create_test_steps_tr(self, test_step_main_div, user_id,
                                  status_code, request_headers_main_div):
            test_steps_tr = html.tr(class_="steps_table_tr")

            test_steps_tr.append(
                html.td(test_step_main_div, class_="tr_step_name"))
            test_steps_tr.append(
                html.td(raw(user_id), class_="tr_step_user_id"))
            test_steps_tr.append(
                html.td(raw(status_code), class_="tr_step_status_code"))
            test_steps_tr.append(
                html.td(request_headers_main_div,
                        class_="tr_step_request_headers"))

            return test_steps_tr
Exemplo n.º 47
0
    def make_table_rows(self, results):
        rv = []
        for key in results.keys():
            result = results[key]['results']
            cells = [html.td(key, class_="col-subsuite")]
            if result.has_errors:
                cells.append(
                    html.td(
                        len(result.errors),
                        class_="condition FAIL col-subsuite",
                    ))
            else:
                cells.append(html.td("0", class_="condition PASS"))
            style = ''
            if result.has_fails or result.has_errors:
                style = 'background-color: darkblue;'
            if result.has_regressions:
                num_regressions = sum(
                    len(item) for item in result.regressions.itervalues())
                cells.append(
                    html.td(num_regressions,
                            class_="condition PASS",
                            style=style))
            else:
                cells.append(html.td("0", class_="condition PASS"))

            details_link = 'data:text/html;charset=utf-8;base64,%s' % base64.b64encode(
                results[key]['html_str'])
            ulbody = [
                html.li(
                    html.a("subsuite report",
                           href=details_link,
                           target='_blank'))
            ]
            files = results[key]['files']
            for fname in files.keys():
                href = '%s/%s' % (key, fname)
                #if key[-4:] == 'html' or key[-3:] == 'htm':
                #    href = 'data:text/html;charset=utf-8;base64,%s' % base64.b64encode(files[key])
                #else:
                #    href = 'data:text/plain;charset=utf-8;base64,%s' % base64.b64encode(files[key])
                ulbody.append(
                    html.li(html.a(fname, href=href, target='_blank')))

            cells.append(html.td(html.ul(ulbody), class_="details"))
            rv.append(html.tr(cells, class_='results-table-row'))

        return rv
Exemplo n.º 48
0
    def make_body(self):
        body_parts = [html.div(
             html.script(raw(pkg_resources.resource_string(
                rcname, os.path.sep.join(['resources', 'htmlreport', 
                    'jquery.js']))),
                type='text/javascript'),
            html.script(raw(pkg_resources.resource_string(
                rcname, os.path.sep.join(['resources', 'htmlreport', 
                    'main.js']))),
                type='text/javascript'),
            html.h1("FirefoxOS Certification Suite Report"),
            html.p("Run at %s" % self.time.strftime("%Y-%m-%d %H:%M:%S"))
            )]
        if self.logs:
            device_profile_object = None
            with open(self.logs[-1]) as f:
                device_profile_object = json.load(f)['result']['contact']
            device_profile = [html.h2('Device Information')]
            device_table = html.table()
            for key in device_profile_object:
                device_table.append(
                    html.tr(
                        html.td(key),
                        html.td(device_profile_object[key])
                    )
                )
                #device_profile.append(html.p("%s, %s"% (key, device_profile_object[key])))
            device_profile.append(device_table)
            body_parts.extend(device_profile);

        if self.summary_results.has_errors:
            body_parts.append(html.h2("Errors During Run"))
            body_parts.append(self.make_errors_table(self.summary_results.errors))
        body_parts.append(html.h2("Test Results"))
        body_parts.append(self.make_result_table())

        if self.logs:
            ulbody = [];
            for log_path in self.logs:
                details_log = ''
                with open(log_path, 'r') as f:
                    details_log = f.read()
                href = 'data:text/plain;charset=utf-8;base64,%s' % base64.b64encode(details_log)
                ulbody.append(html.li(html.a(os.path.basename(log_path), href=href, target='_blank')))
            device_profile_object = None
            body_parts.append(html.h2("Details log information"))
            body_parts.append(html.ul(ulbody))
        return html.body(body_parts)
Exemplo n.º 49
0
    def _generate_environment(self, config):
        if not hasattr(config, '_metadata') or config._metadata is None:
            return []

        metadata = config._metadata
        environment = [html.h2('Environment')]
        rows = []

        for key in [k for k in sorted(metadata.keys()) if metadata[k]]:
            value = metadata[key]
            if isinstance(value, basestring) and value.startswith('http'):
                value = html.a(value, href=value, target='_blank')
            rows.append(html.tr(html.td(key), html.td(value)))

        environment.append(html.table(rows, id='environment'))
        return environment
Exemplo n.º 50
0
    def _appendrow(self, result, report):
        names = mangle_testnames(report.nodeid.split("::"))
        testclass = (names[:-1])
        if self.prefix:
            testclass.insert(0, self.prefix)
        testclass = ".".join(testclass)
        testmethod = names[-1]
        time = getattr(report, 'duration', 0.0)

        additional_html = []

        if not 'Passed' in result:
            if report.longrepr:
                log = html.div(class_='log')
                for line in str(report.longrepr).splitlines():
                    line = line.decode('utf8')
                    separator = line.startswith('_ ' * 10)
                    if separator:
                        log.append(line[:80])
                    else:
                        exception = line.startswith("E   ")
                        if exception:
                            log.append(html.span(raw(cgi.escape(line)),
                                                 class_='error'))
                        else:
                            log.append(raw(cgi.escape(line)))
                    log.append(html.br())
                if not os.path.exists(self.screenshot_path):
                    os.makedirs(self.screenshot_path)
                self.append_screenshot(testmethod, log)
                additional_html.append(log)
        output = self._write_captured_output(report)
        info = output.split(" ")
        links_html = []
        for i in range(0, len(info)):
            if ("http" in info[i] and "browserstack.com" in info[i]):
                links_html.append(html.a("link", href=info[i], target='_blank'))
                links_html.append(' ')

        self.test_logs.append(html.tr([
                                          html.td(result, class_='col-result'),
                                          html.td(testclass, class_='col-class'),
                                          html.td(testmethod, class_='col-name'),
                                          html.td(round(time), class_='col-duration'),
                                          html.td(links_html, class_='col-links'),
                                          html.td(additional_html, class_='debug')],
                                      class_=result.lower() + ' results-table-row'))
Exemplo n.º 51
0
def create_dir_html(path, href_prefix=''):
    h = html.html(
        html.head(
            html.title('directory listing of %s' % (path,)),
            style,
        ),
    )
    body = html.body(
        html.h1('directory listing of %s' % (path,)),
    )
    h.append(body)
    table = html.table()
    body.append(table)
    tbody = html.tbody()
    table.append(tbody)
    items = list(path.listdir())
    items.sort(key=lambda p: p.basename)
    items.sort(key=lambda p: not p.check(dir=True))
    for fpath in items:
        tr = html.tr()
        tbody.append(tr)
        td1 = html.td(fpath.check(dir=True) and 'D' or 'F', class_='type')
        tr.append(td1)
        href = fpath.basename
        if href_prefix:
            href = '%s%s' % (href_prefix, href)
        if fpath.check(dir=True):
            href += '/'
        td2 = html.td(html.a(fpath.basename, href=href), class_='name')
        tr.append(td2)
        td3 = html.td(time.strftime('%Y-%m-%d %H:%M:%S',
                      time.gmtime(fpath.mtime())), class_='mtime')
        tr.append(td3)
        if fpath.check(dir=True):
            size = ''
            unit = ''
        else:
            size = fpath.size()
            unit = 'B'
            for u in ['kB', 'MB', 'GB', 'TB']:
                if size > 1024:
                    size = round(size / 1024.0, 2)
                    unit = u
        td4 = html.td('%s %s' % (size, unit), class_='size')
        tr.append(td4)
    return unicode(h)
Exemplo n.º 52
0
    def _appendrow(self, result, report):
        testclass = self.prefix + " " + self.current_test_info['package'] + self.current_test_info['class']
        testmethod = self.current_test_info['name']

        duration = getattr(report, 'duration', 0.0)

        additional_html = []
        links_html = []

        log = html.div(class_='log')

        if report.passed:
            log.append('Your tests are passing, but you are still curious. I like it :)')

        else:

            if hasattr(report, 'wasxfail'):
                self._append_xpass_section(log, report)

            if not report.skipped:
                self._append_crash_message_section(log, report)
                self._append_screenshot(testmethod, log)

                self._append_stacktrace_section(log, report)

                links_html.append(self._link_to_debug_event(testmethod, log))

        output = self._append_captured_output(log, report)

        additional_html.append(log)

        links_html.append(self._link_to_browserstack_log(output))

        self.test_logs.append(html.tr([
            html.td(result, class_='col-result'),
            html.td(testclass, class_='col-class'),
            html.td(testmethod, class_='col-name'),
            html.td(round(duration), class_='col-duration'),
            html.td(links_html, class_='col-links'),
            html.td(additional_html, class_='debug')],
            class_=result.lower() + ' results-table-row'))
Exemplo n.º 53
0
 def make_errors_table(self, errors):
     rows = []
     for error in errors:
         error_message = error.get("message", "")
         log = html.div(class_='log')
         for line in error_message.splitlines():
             separator = line.startswith(' ' * 10)
             if separator:
                 log.append(line[:80])
             else:
                 if line.lower().find("error") != -1 or line.lower().find("exception") != -1:
                     log.append(html.span(raw(cgi.escape(line)), class_='error'))
                 else:
                     log.append(raw(cgi.escape(line)))
             log.append(html.br())
         rows.append(html.tr(
             html.td(error["level"],
                     class_="log_%s" % error["level"]),
             html.td(log, class_='log')
         ))
     return html.table(rows, id_="errors")
Exemplo n.º 54
0
    def _generate_environment(self, config):
        if not hasattr(config, '_metadata') or config._metadata is None:
            return []

        metadata = config._metadata
        environment = [html.h2('Environment')]
        rows = []

        keys = [k for k in metadata.keys()]
        if not isinstance(metadata, OrderedDict):
            keys.sort()

        for key in keys:
            value = metadata[key]
            if isinstance(value, basestring) and value.startswith('http'):
                value = html.a(value, href=value, target='_blank')
            elif isinstance(value, (list, tuple, set)):
                value = ', '.join((str(i) for i in value))
            rows.append(html.tr(html.td(key), html.td(value)))

        environment.append(html.table(rows, id='environment'))
        return environment
Exemplo n.º 55
0
    def _generate_environment(self, config):
        if not hasattr(config, '_metadata') or config._metadata is None:
            return []

        metadata = config._metadata
        environment = [html.h2('Environment')]
        rows = []

        keys = [k for k in metadata.keys() if metadata[k]]
        if not isinstance(metadata, OrderedDict):
            keys.sort()

        for key in keys:
            value = metadata[key]
            if isinstance(value, basestring) and value.startswith('http'):
                value = html.a(value, href=value, target='_blank')
            elif isinstance(value, (list, tuple, set)):
                value = ', '.join((str(i) for i in value))
            rows.append(html.tr(html.td(key), html.td(value)))

        environment.append(html.table(rows, id='environment'))
        return environment
Exemplo n.º 56
0
 def make_errors_table(self, errors):
     rows = []
     for error in errors:
         error_message = error.get("message", "")
         log = html.div(class_='log')
         for line in error_message.splitlines():
             separator = line.startswith(' ' * 10)
             if separator:
                 log.append(line[:80])
             else:
                 if line.lower().find("error") != -1 or line.lower().find(
                         "exception") != -1:
                     log.append(
                         html.span(raw(cgi.escape(line)), class_='error'))
                 else:
                     log.append(raw(cgi.escape(line)))
             log.append(html.br())
         rows.append(
             html.tr(
                 html.td(error["level"], class_="log_%s" % error["level"]),
                 html.td(log, class_='log')))
     return html.table(rows, id_="errors")
Exemplo n.º 57
0
    def make_table_rows(self, results):
        rv = []
        for key in results.keys():
            result = results[key]['results']
            cells = [html.td(key, class_="col-subsuite")]
            if result.has_errors:
                cells.append(html.td(
                    len(result.errors),
                    class_="condition FAIL col-subsuite",
                ))
            else:
                cells.append(html.td("0",
                                     class_="condition PASS"))
            style = ''
            if result.has_fails or result.has_errors:
                style = 'background-color: darkblue;'
            if result.has_regressions:
                num_regressions = sum(len(item) for item in result.regressions.itervalues())
                cells.append(html.td(num_regressions, class_="condition PASS", style=style))
            else:
                cells.append(html.td("0", class_="condition PASS"))
            
            details_link = 'data:text/html;charset=utf-8;base64,%s' % base64.b64encode(results[key]['html_str'])
            ulbody = [html.li(html.a("subsuite report", href=details_link, target='_blank'))]
            files = results[key]['files']
            for fname in files.keys():
                href = '%s/%s' % (key, fname)
                #if key[-4:] == 'html' or key[-3:] == 'htm':
                #    href = 'data:text/html;charset=utf-8;base64,%s' % base64.b64encode(files[key])
                #else:
                #    href = 'data:text/plain;charset=utf-8;base64,%s' % base64.b64encode(files[key])
                ulbody.append(html.li(html.a(fname, href=href, target='_blank')))
            
            cells.append(html.td(html.ul(ulbody), class_="details"))
            rv.append(html.tr(cells, class_='results-table-row'))

        return rv
Exemplo n.º 58
0
    def _generate_report(self, session):
        suite_stop_time = time.time()
        suite_time_delta = suite_stop_time - self.suite_start_time
        numtests = self.passed + self.failed + self.xpassed + self.xfailed
        generated = datetime.datetime.now()

        self.style_css = pkg_resources.resource_string(
            __name__, os.path.join("resources", "style.css")).decode("utf-8")

        if ANSI:
            ansi_css = [
                "\n/******************************",
                " * ANSI2HTML STYLES",
                " ******************************/\n",
            ]
            ansi_css.extend([str(r) for r in style.get_styles()])
            self.style_css += "\n".join(ansi_css)

        # <DF> Add user-provided CSS
        for path in self.config.getoption("css"):
            self.style_css += "\n/******************************"
            self.style_css += "\n * CUSTOM CSS"
            self.style_css += f"\n * {path}"
            self.style_css += "\n ******************************/\n\n"
            with open(path, "r") as f:
                self.style_css += f.read()

        css_href = "assets/style.css"
        html_css = html.link(href=css_href, rel="stylesheet", type="text/css")
        if self.self_contained:
            html_css = html.style(raw(self.style_css))

        head = html.head(
            html.meta(charset="utf-8"),
            html.meta(
                content=
                "width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0, user-scalable=no"
            ), html.title("Test Report"), html_css)

        class Outcome:
            def __init__(self,
                         outcome,
                         total=0,
                         label=None,
                         test_result=None,
                         class_html=None):
                self.outcome = outcome
                self.label = label or outcome
                self.class_html = class_html or outcome
                self.total = total
                self.test_result = test_result or outcome

                self.generate_checkbox()
                self.generate_summary_item()

            def generate_checkbox(self):
                checkbox_kwargs = {
                    "data-test-result": self.test_result.lower()
                }
                if self.total == 0:
                    checkbox_kwargs["disabled"] = "true"

                self.checkbox = html.input(
                    type="checkbox",
                    checked="true",
                    onChange="filter_table(this)",
                    name="filter_checkbox",
                    class_="filter",
                    hidden="true",
                    **checkbox_kwargs,
                )

            def generate_summary_item(self):
                self.summary_item = html.span(f"{self.total} {self.label}",
                                              class_=self.class_html)

        outcomes = [
            Outcome("passed", self.passed),
            Outcome("skipped", self.skipped),
            Outcome("failed", self.failed),
            Outcome("error", self.errors, label="errors"),
            Outcome("xfailed", self.xfailed, label="expected failures"),
            Outcome("xpassed", self.xpassed, label="unexpected passes"),
        ]

        if self.rerun is not None:
            outcomes.append(Outcome("rerun", self.rerun))

        summary = [
            html.p(
                f"{numtests} tests ran in {suite_time_delta:.2f} seconds. "),
            html.p(
                "(Un)check the boxes to filter the results.",
                class_="filter",
                hidden="true",
            ),
        ]

        for i, outcome in enumerate(outcomes, start=1):
            summary.append(outcome.checkbox)
            summary.append(outcome.summary_item)
            if i < len(outcomes):
                summary.append(", ")

        cells = [
            html.th("Result",
                    class_="sortable result initial-sort",
                    col="result"),
            html.th("Test", class_="sortable", col="name"),
            html.th("Duration", class_="sortable numeric", col="duration"),
            html.th("Links"),
        ]
        session.config.hook.pytest_html_results_table_header(cells=cells)

        results = [
            html.h2("Results"),
            html.table(
                [
                    html.thead(
                        html.tr(cells),
                        html.tr(
                            [
                                html.th(
                                    "No results found. Try to check the filters",
                                    colspan=len(cells),
                                )
                            ],
                            id="not-found-message",
                            hidden="true",
                        ),
                        id="results-table-head",
                    ),
                    self.test_logs,
                ],
                id="results-table",
            ),
        ]

        main_js = pkg_resources.resource_string(
            __name__, os.path.join("resources", "main.js")).decode("utf-8")

        report_title = self.logfile.split('/')[-4] + '测试报告如下:'
        body = html.body(
            html.script(raw(main_js)),
            # html.h1(os.path.basename(self.logfile)),
            html.h1(report_title),  # 测试报告title
            html.
            p("Report generated on {} at {}.".format(
                generated.strftime("%Y-%m-%d"),
                generated.strftime("%H:%M:%S")),
              # html.a("pytest-html", href=__pypi_url__),
              # f" v{__version__}",
              ),
            onLoad="init()",
        )

        body.extend(self._generate_environment(session.config))

        summary_prefix, summary_postfix = [], []
        session.config.hook.pytest_html_results_summary(
            prefix=summary_prefix, summary=summary, postfix=summary_postfix)
        body.extend([html.h2("Summary")] + summary_prefix + summary +
                    summary_postfix)

        body.extend(results)

        doc = html.html(head, body)

        unicode_doc = "<!DOCTYPE html>\n{}".format(doc.unicode(indent=2))

        # Fix encoding issues, e.g. with surrogates
        unicode_doc = unicode_doc.encode("utf-8", errors="xmlcharrefreplace")
        return unicode_doc.decode("utf-8")
Exemplo n.º 59
0
    def generate_html(self, results_list):

        tests = sum([results.testsRun for results in results_list])
        failures = sum([len(results.failures) for results in results_list])
        expected_failures = sum([len(results.expectedFailures) for results in results_list])
        skips = sum([len(results.skipped) for results in results_list])
        errors = sum([len(results.errors) for results in results_list])
        passes = sum([results.passed for results in results_list])
        unexpected_passes = sum([len(results.unexpectedSuccesses) for results in results_list])
        test_time = self.elapsedtime.total_seconds()
        test_logs = []

        def _extract_html(test, class_name, duration=0, text="", result="passed", debug=None):
            cls_name = class_name
            tc_name = unicode(test)
            tc_time = duration
            additional_html = []
            debug = debug or {}
            links_html = []

            if result in ["skipped", "failure", "expected failure", "error"]:
                if debug.get("screenshot"):
                    screenshot = "data:image/png;base64,%s" % debug["screenshot"]
                    additional_html.append(html.div(html.a(html.img(src=screenshot), href="#"), class_="screenshot"))
                for name, content in debug.items():
                    try:
                        if "screenshot" in name:
                            href = "#"
                        else:
                            # use base64 to avoid that some browser (such as Firefox, Opera)
                            # treats '#' as the start of another link if the data URL contains.
                            # use 'charset=utf-8' to show special characters like Chinese.
                            href = "data:text/plain;charset=utf-8;base64,%s" % base64.b64encode(content)
                        links_html.append(html.a(name.title(), class_=name, href=href, target="_blank"))
                        links_html.append(" ")
                    except:
                        pass

                log = html.div(class_="log")
                for line in text.splitlines():
                    separator = line.startswith(" " * 10)
                    if separator:
                        log.append(line[:80])
                    else:
                        if line.lower().find("error") != -1 or line.lower().find("exception") != -1:
                            log.append(html.span(raw(cgi.escape(line)), class_="error"))
                        else:
                            log.append(raw(cgi.escape(line)))
                    log.append(html.br())
                additional_html.append(log)

            test_logs.append(
                html.tr(
                    [
                        html.td(result.title(), class_="col-result"),
                        html.td(cls_name, class_="col-class"),
                        html.td(tc_name, class_="col-name"),
                        html.td(tc_time, class_="col-duration"),
                        html.td(links_html, class_="col-links"),
                        html.td(additional_html, class_="debug"),
                    ],
                    class_=result.lower() + " results-table-row",
                )
            )

        for results in results_list:
            for test in results.tests_passed:
                _extract_html(test.name, test.test_class)
            for result in results.skipped:
                _extract_html(result.name, result.test_class, text="\n".join(result.output), result="skipped")
            for result in results.failures:
                _extract_html(
                    result.name, result.test_class, text="\n".join(result.output), result="failure", debug=result.debug
                )
            for result in results.expectedFailures:
                _extract_html(
                    result.name,
                    result.test_class,
                    text="\n".join(result.output),
                    result="expected failure",
                    debug=result.debug,
                )
            for test in results.unexpectedSuccesses:
                _extract_html(test.name, test.test_class, result="unexpected pass")
            for result in results.errors:
                _extract_html(
                    result.name, result.test_class, text="\n".join(result.output), result="error", debug=result.debug
                )

        generated = datetime.datetime.now()
        doc = html.html(
            html.head(
                html.meta(charset="utf-8"),
                html.title("Test Report"),
                html.style(
                    raw(
                        pkg_resources.resource_string(__name__, os.path.sep.join(["resources", "report", "style.css"]))
                    ),
                    type="text/css",
                ),
            ),
            html.body(
                html.script(
                    raw(
                        pkg_resources.resource_string(__name__, os.path.sep.join(["resources", "report", "jquery.js"]))
                    ),
                    type="text/javascript",
                ),
                html.script(
                    raw(pkg_resources.resource_string(__name__, os.path.sep.join(["resources", "report", "main.js"]))),
                    type="text/javascript",
                ),
                html.p(
                    "Report generated on %s at %s by %s %s"
                    % (generated.strftime("%d-%b-%Y"), generated.strftime("%H:%M:%S"), __name__, __version__)
                ),
                html.h2("Summary"),
                html.p(
                    "%i tests ran in %i seconds." % (tests, test_time),
                    html.br(),
                    html.span("%i passed" % passes, class_="passed"),
                    ", ",
                    html.span("%i skipped" % skips, class_="skipped"),
                    ", ",
                    html.span("%i failed" % failures, class_="failed"),
                    ", ",
                    html.span("%i errors" % errors, class_="error"),
                    ".",
                    html.br(),
                    html.span("%i expected failures" % expected_failures, class_="expected failure"),
                    ", ",
                    html.span("%i unexpected passes" % unexpected_passes, class_="unexpected pass"),
                    ".",
                ),
                html.h2("Results"),
                html.table(
                    [
                        html.thead(
                            html.tr(
                                [
                                    html.th("Result", class_="sortable", col="result"),
                                    html.th("Class", class_="sortable", col="class"),
                                    html.th("Test Name", class_="sortable", col="name"),
                                    html.th("Duration", class_="sortable numeric", col="duration"),
                                    html.th("Links"),
                                ]
                            ),
                            id="results-table-head",
                        ),
                        html.tbody(test_logs, id="results-table-body"),
                    ],
                    id="results-table",
                ),
            ),
        )
        return doc.unicode(indent=2)
Exemplo n.º 60
0
    def generate_html(self, results_list):

        tests = sum([results.testsRun for results in results_list])
        failures = sum([len(results.failures) for results in results_list])
        expected_failures = sum(
            [len(results.expectedFailures) for results in results_list])
        skips = sum([len(results.skipped) for results in results_list])
        errors = sum([len(results.errors) for results in results_list])
        passes = sum([results.passed for results in results_list])
        unexpected_passes = sum(
            [len(results.unexpectedSuccesses) for results in results_list])
        test_time = self.elapsedtime.total_seconds()
        test_logs = []

        def _extract_html(test,
                          class_name,
                          duration=0,
                          text='',
                          result='passed',
                          debug=None):
            cls_name = class_name
            tc_name = unicode(test)
            tc_time = duration
            additional_html = []
            debug = debug or {}
            links_html = []

            if result in ['skipped', 'failure', 'expected failure', 'error']:
                if debug.get('screenshot'):
                    screenshot = 'data:image/png;base64,%s' % debug[
                        'screenshot']
                    additional_html.append(
                        html.div(html.a(html.img(src=screenshot), href="#"),
                                 class_='screenshot'))
                for name, content in debug.items():
                    try:
                        if 'screenshot' in name:
                            href = '#'
                        else:
                            # use base64 to avoid that some browser (such as Firefox, Opera)
                            # treats '#' as the start of another link if the data URL contains.
                            # use 'charset=utf-8' to show special characters like Chinese.
                            href = 'data:text/plain;charset=utf-8;base64,%s' % base64.b64encode(
                                content)
                        links_html.append(
                            html.a(name.title(),
                                   class_=name,
                                   href=href,
                                   target='_blank'))
                        links_html.append(' ')
                    except:
                        pass

                log = html.div(class_='log')
                for line in text.splitlines():
                    separator = line.startswith(' ' * 10)
                    if separator:
                        log.append(line[:80])
                    else:
                        if line.lower().find("error") != -1 or line.lower(
                        ).find("exception") != -1:
                            log.append(
                                html.span(raw(cgi.escape(line)),
                                          class_='error'))
                        else:
                            log.append(raw(cgi.escape(line)))
                    log.append(html.br())
                additional_html.append(log)

            test_logs.append(
                html.tr([
                    html.td(result.title(), class_='col-result'),
                    html.td(cls_name, class_='col-class'),
                    html.td(tc_name, class_='col-name'),
                    html.td(tc_time, class_='col-duration'),
                    html.td(links_html, class_='col-links'),
                    html.td(additional_html, class_='debug')
                ],
                        class_=result.lower() + ' results-table-row'))

        for results in results_list:
            for test in results.tests_passed:
                _extract_html(test.name, test.test_class)
            for result in results.skipped:
                _extract_html(result.name,
                              result.test_class,
                              text='\n'.join(result.output),
                              result='skipped')
            for result in results.failures:
                _extract_html(result.name,
                              result.test_class,
                              text='\n'.join(result.output),
                              result='failure',
                              debug=result.debug)
            for result in results.expectedFailures:
                _extract_html(result.name,
                              result.test_class,
                              text='\n'.join(result.output),
                              result='expected failure',
                              debug=result.debug)
            for test in results.unexpectedSuccesses:
                _extract_html(test.name,
                              test.test_class,
                              result='unexpected pass')
            for result in results.errors:
                _extract_html(result.name,
                              result.test_class,
                              text='\n'.join(result.output),
                              result='error',
                              debug=result.debug)

        generated = datetime.datetime.now()
        doc = html.html(
            html.head(
                html.meta(charset='utf-8'), html.title('Test Report'),
                html.style(raw(
                    pkg_resources.resource_string(
                        __name__,
                        os.path.sep.join(['resources', 'report',
                                          'style.css']))),
                           type='text/css')),
            html.body(
                html.script(raw(
                    pkg_resources.resource_string(
                        __name__,
                        os.path.sep.join(['resources', 'report',
                                          'jquery.js']))),
                            type='text/javascript'),
                html.script(raw(
                    pkg_resources.resource_string(
                        __name__,
                        os.path.sep.join(['resources', 'report', 'main.js']))),
                            type='text/javascript'),
                html.p(
                    'Report generated on %s at %s by %s %s' %
                    (generated.strftime('%d-%b-%Y'),
                     generated.strftime('%H:%M:%S'), __name__, __version__)),
                html.h2('Summary'),
                html.p(
                    '%i tests ran in %i seconds.' % (tests, test_time),
                    html.br(), html.span('%i passed' % passes,
                                         class_='passed'), ', ',
                    html.span('%i skipped' % skips, class_='skipped'), ', ',
                    html.span('%i failed' % failures, class_='failed'), ', ',
                    html.span('%i errors' % errors, class_='error'), '.',
                    html.br(),
                    html.span('%i expected failures' % expected_failures,
                              class_='expected failure'), ', ',
                    html.span('%i unexpected passes' % unexpected_passes,
                              class_='unexpected pass'), '.'),
                html.h2('Results'),
                html.table([
                    html.thead(html.tr([
                        html.th('Result', class_='sortable', col='result'),
                        html.th('Class', class_='sortable', col='class'),
                        html.th('Test Name', class_='sortable', col='name'),
                        html.th('Duration',
                                class_='sortable numeric',
                                col='duration'),
                        html.th('Links')
                    ]),
                               id='results-table-head'),
                    html.tbody(test_logs, id='results-table-body')
                ],
                           id='results-table')))
        return doc.unicode(indent=2)