From 4552a238116dbbd0091a8e0175ef742536b2941f Mon Sep 17 00:00:00 2001 From: werdeil Date: Fri, 20 Mar 2020 13:42:51 +0100 Subject: [PATCH 1/4] Do not handle Tags as list in envirnoment table --- pytest_html/plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pytest_html/plugin.py b/pytest_html/plugin.py index 45a4f500..1eacc281 100644 --- a/pytest_html/plugin.py +++ b/pytest_html/plugin.py @@ -25,7 +25,7 @@ # ansi2html is not installed ANSI = False -from py.xml import html, raw +from py.xml import html, raw, Tag from . import extras from . import __version__, __pypi_url__ @@ -571,7 +571,7 @@ def _generate_environment(self, config): 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)): + elif isinstance(value, (list, tuple, set)) and not isinstance(value, Tag): 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)} From 67317918077c6fba5662a82f8f07c9bdabb396f5 Mon Sep 17 00:00:00 2001 From: werdeil Date: Fri, 20 Mar 2020 15:01:30 +0100 Subject: [PATCH 2/4] Break out environment generation into its own class --- README.rst | 15 ++++++++++ pytest_html/hooks.py | 8 ++++++ pytest_html/plugin.py | 64 ++++++++++++++++++++++++++----------------- 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/README.rst b/README.rst index 449cd815..46cb3460 100644 --- a/README.rst +++ b/README.rst @@ -115,6 +115,21 @@ via the :code:`pytest_configure` hook: The generated table will be sorted alphabetically unless the metadata is a :code:`collections.OrderedDict`. +You can edit the environment table header and row by using the :code:`pytest_html_environment_table_header` and `pytest_html_environment_table_row` hooks: + +.. code-block:: python + + import pytest + + DESCRIPTION_DICT = {"Packages": "Version of pytest packages", "Python": "Version of Python"} + + def pytest_html_environment_table_header(cells): + cells.insert(2, html.th('Description')) + + def pytest_html_environment_table_row(cells): + cells.insert(2, html.td(description_dict.get(cells[0], ''))) + + Additional summary information ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/pytest_html/hooks.py b/pytest_html/hooks.py index 7b75120b..4358c125 100644 --- a/pytest_html/hooks.py +++ b/pytest_html/hooks.py @@ -7,6 +7,14 @@ def pytest_html_report_title(report): """ Called before adding the title to the report """ +def pytest_html_environment_table_header(cells): + """ Called after building environment table header. """ + + +def pytest_html_environment_table_row(cells): + """ Called after building environment table row. """ + + def pytest_html_results_summary(prefix, summary, postfix): """ Called before adding the summary section to the report """ diff --git a/pytest_html/plugin.py b/pytest_html/plugin.py index 1eacc281..a7a4355d 100644 --- a/pytest_html/plugin.py +++ b/pytest_html/plugin.py @@ -25,7 +25,7 @@ # ansi2html is not installed ANSI = False -from py.xml import html, raw, Tag +from py.xml import html, raw from . import extras from . import __version__, __pypi_url__ @@ -341,6 +341,38 @@ def _append_video(self, extra, extra_index, test_index): ) self.additional_html.append(html.div(html_div, class_="video")) + class EnvironmentTable: + def __init__(self, config): + self.metadata = getattr(config, "_metadata", []) + self.config = config + self.environment_table = [] + + rows = [] + + header_cells = [html.th("Key"), html.th("Value")] + self.config.hook.pytest_html_environment_table_header(cells=header_cells) + rows.append(header_cells) + if self.metadata: + keys = [k for k in self.metadata.keys()] + if not isinstance(self.metadata, OrderedDict): + keys.sort() + + for key in keys: + value = self.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)) + row_cells = html.tr(html.td(key), html.td(raw_value_string)) + self.config.hook.pytest_html_environment_table_row(cells=row_cells) + rows.append(row_cells) + + self.environment_table.append(html.table(rows, id="environment")) + def _appendrow(self, outcome, report): result = self.TestResult(outcome, report, self.logfile, self.config) if result.row_table is not None: @@ -556,30 +588,12 @@ def generate_summary_item(self): return unicode_doc.decode("utf-8") 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)) and not isinstance(value, Tag): - 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(key), html.td(raw_value_string))) - - environment.append(html.table(rows, id="environment")) + environment_table = self.EnvironmentTable(config).environment_table + if environment_table: + environment = [html.h2("Environment")] + environment.append(environment_table) + else: + environment = [] return environment def _save_report(self, report_content): From 8e14277758e09e3f1a6d3e4c69a3f0086ea77c39 Mon Sep 17 00:00:00 2001 From: werdeil Date: Mon, 23 Mar 2020 16:24:38 +0100 Subject: [PATCH 3/4] First attempt to break __init__ in smaller functions --- pytest_html/plugin.py | 66 +++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/pytest_html/plugin.py b/pytest_html/plugin.py index a7a4355d..83e61746 100644 --- a/pytest_html/plugin.py +++ b/pytest_html/plugin.py @@ -341,37 +341,52 @@ def _append_video(self, extra, extra_index, test_index): ) self.additional_html.append(html.div(html_div, class_="video")) - class EnvironmentTable: + class EnvironmentSection: def __init__(self, config): self.metadata = getattr(config, "_metadata", []) self.config = config + self.environment = [] self.environment_table = [] - rows = [] - - header_cells = [html.th("Key"), html.th("Value")] - self.config.hook.pytest_html_environment_table_header(cells=header_cells) - rows.append(header_cells) if self.metadata: + self.rows = [] + self._generate_environment_header() + keys = [k for k in self.metadata.keys()] if not isinstance(self.metadata, OrderedDict): keys.sort() for key in keys: - value = self.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)) - row_cells = html.tr(html.td(key), html.td(raw_value_string)) - self.config.hook.pytest_html_environment_table_row(cells=row_cells) - rows.append(row_cells) - - self.environment_table.append(html.table(rows, id="environment")) + self._generate_environment_row(key) + + self._generate_environment_section() + + def _generate_environment_header(self): + header_cells = [html.th("Key"), html.th("Value")] + self.config.hook.pytest_html_environment_table_header(cells=header_cells) + self.rows.append(header_cells) + + def _generate_environment_row(self, key): + value = self.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)) + row_cells = html.tr(html.td(key), html.td(raw_value_string)) + self.config.hook.pytest_html_environment_table_row(cells=row_cells) + self.rows.append(row_cells) + + def _generate_environment_table(self): + self.environment_table.append(html.table(self.rows, id="environment")) + + def _generate_environment_section(self): + if self.environment_table: + self.environment = [html.h2("Environment")] + self.environment.append(self.environment_table) def _appendrow(self, outcome, report): result = self.TestResult(outcome, report, self.logfile, self.config) @@ -569,7 +584,7 @@ def generate_summary_item(self): onLoad="init()", ) - body.extend(self._generate_environment(session.config)) + body.extend(self.EnvironmentSection(session.config).environment_table) summary_prefix, summary_postfix = [], [] session.config.hook.pytest_html_results_summary( @@ -587,15 +602,6 @@ def generate_summary_item(self): unicode_doc = unicode_doc.encode("utf-8", errors="xmlcharrefreplace") return unicode_doc.decode("utf-8") - def _generate_environment(self, config): - environment_table = self.EnvironmentTable(config).environment_table - if environment_table: - environment = [html.h2("Environment")] - environment.append(environment_table) - else: - environment = [] - return environment - def _save_report(self, report_content): dir_name = os.path.dirname(self.logfile) assets_dir = os.path.join(dir_name, "assets") From 90a6bb73eb6c7515e1d8d5f28801c5534432a453 Mon Sep 17 00:00:00 2001 From: Vincent VERDEIL Date: Mon, 18 May 2020 17:12:51 +0200 Subject: [PATCH 4/4] Correct failing tests --- pytest_html/plugin.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pytest_html/plugin.py b/pytest_html/plugin.py index 83e61746..088a71e0 100644 --- a/pytest_html/plugin.py +++ b/pytest_html/plugin.py @@ -347,9 +347,9 @@ def __init__(self, config): self.config = config self.environment = [] self.environment_table = [] + self.rows = [] if self.metadata: - self.rows = [] self._generate_environment_header() keys = [k for k in self.metadata.keys()] @@ -380,11 +380,9 @@ def _generate_environment_row(self, key): self.config.hook.pytest_html_environment_table_row(cells=row_cells) self.rows.append(row_cells) - def _generate_environment_table(self): - self.environment_table.append(html.table(self.rows, id="environment")) - def _generate_environment_section(self): - if self.environment_table: + if self.rows: + self.environment_table.append(html.table(self.rows, id="environment")) self.environment = [html.h2("Environment")] self.environment.append(self.environment_table) @@ -584,7 +582,7 @@ def generate_summary_item(self): onLoad="init()", ) - body.extend(self.EnvironmentSection(session.config).environment_table) + body.extend(self.EnvironmentSection(session.config).environment) summary_prefix, summary_postfix = [], [] session.config.hook.pytest_html_results_summary(