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 39f8a677..6bcd29f1 100644 --- a/pytest_html/plugin.py +++ b/pytest_html/plugin.py @@ -355,6 +355,51 @@ def _append_video(self, extra, extra_index, test_index): ) self.additional_html.append(html.div(html_div, class_="video")) + class EnvironmentSection: + def __init__(self, config): + self.metadata = getattr(config, "_metadata", []) + self.config = config + self.environment = [] + self.environment_table = [] + self.rows = [] + + if self.metadata: + self._generate_environment_header() + + keys = [k for k in self.metadata.keys()] + if not isinstance(self.metadata, OrderedDict): + keys.sort() + + for key in keys: + 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_section(self): + if self.rows: + self.environment_table.append(html.table(self.rows, id="environment")) + 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) if result.row_table is not None: @@ -551,7 +596,7 @@ def generate_summary_item(self): onLoad="init()", ) - body.extend(self._generate_environment(session.config)) + body.extend(self.EnvironmentSection(session.config).environment) summary_prefix, summary_postfix = [], [] session.config.hook.pytest_html_results_summary( @@ -569,33 +614,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): - 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): - 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")) - return environment - def _save_report(self, report_content): dir_name = os.path.dirname(self.logfile) assets_dir = os.path.join(dir_name, "assets")