diff --git a/src/pytest_html/basereport.py b/src/pytest_html/basereport.py index e5e61591..7e014f58 100644 --- a/src/pytest_html/basereport.py +++ b/src/pytest_html/basereport.py @@ -14,9 +14,11 @@ from pytest_html import __version__ from pytest_html import extras +from pytest_html.table import Header +from pytest_html.table import Html +from pytest_html.table import Row from pytest_html.util import cleanup_unserializable - try: from ansi2html import Ansi2HTMLConverter, style @@ -31,37 +33,6 @@ class BaseReport: - class Cells: - def __init__(self): - self._html = {} - - def __delitem__(self, key): - # This means the item should be removed - self._html = None - - @property - def html(self): - return self._html - - def insert(self, index, html): - # backwards-compat - if not isinstance(html, str): - if html.__module__.startswith("py."): - warnings.warn( - "The 'py' module is deprecated and support " - "will be removed in a future release.", - DeprecationWarning, - ) - html = str(html) - html = html.replace("col", "data-column-type") - self._html[index] = html - - def pop(self, *args): - warnings.warn( - "'pop' is deprecated and no longer supported.", - DeprecationWarning, - ) - class Report: def __init__(self, title, config): self._config = config @@ -100,15 +71,16 @@ def data(self): def set_data(self, key, value): self._data[key] = value - def add_test(self, test_data, report): + def add_test(self, test_data, report, remove_log=False): # regardless of pass or fail we must add teardown logging to "call" - if report.when == "teardown": + if report.when == "teardown" and not remove_log: self.update_test_log(report) # passed "setup" and "teardown" are not added to the html if report.when == "call" or _is_error(report): - processed_logs = _process_logs(report) - test_data["log"] = _handle_ansi(processed_logs) + if not remove_log: + processed_logs = _process_logs(report) + test_data["log"] = _handle_ansi(processed_logs) self._data["tests"][report.nodeid].append(test_data) return True @@ -117,7 +89,7 @@ def add_test(self, test_data, report): def update_test_log(self, report): log = [] for test in self._data["tests"][report.nodeid]: - if test["testId"] == report.nodeid: + if test["testId"] == report.nodeid and "log" in test: for section in report.sections: header, content = section if "teardown" in header: @@ -260,7 +232,7 @@ def pytest_sessionstart(self, session): session.config.hook.pytest_html_report_title(report=self._report) - header_cells = self.Cells() + header_cells = Header() session.config.hook.pytest_html_results_table_header(cells=header_cells) self._report.set_data("resultsTableHeader", header_cells.html) @@ -301,8 +273,9 @@ def pytest_runtest_logreport(self, report): } test_id = report.nodeid + table_html = Html() if report.when == "call": - row_cells = self.Cells() + row_cells = Row() self._config.hook.pytest_html_results_table_row( report=report, cells=row_cells ) @@ -310,11 +283,10 @@ def pytest_runtest_logreport(self, report): return data["resultsTableRow"] = row_cells.html - table_html = [] self._config.hook.pytest_html_results_table_html( report=report, data=table_html ) - data["tableHtml"] = table_html + data["tableHtml"] = table_html.html["html"] else: test_id += f"::{report.when}" data["testId"] = test_id @@ -322,7 +294,7 @@ def pytest_runtest_logreport(self, report): data["result"] = _process_outcome(report) data["extras"] = self._process_extras(report, test_id) - if self._report.add_test(data, report): + if self._report.add_test(data, report, table_html.replace_log): self._generate_report() diff --git a/src/pytest_html/scripts/dom.js b/src/pytest_html/scripts/dom.js index e40a9027..28ad8c29 100644 --- a/src/pytest_html/scripts/dom.js +++ b/src/pytest_html/scripts/dom.js @@ -94,10 +94,11 @@ const dom = { if (log) { - // resultBody.querySelector('.log').innerText = log resultBody.querySelector('.log').innerHTML = log + } else { + resultBody.querySelector('.log').remove() } - // if (collapsed || !longreprtext) { + if (collapsed) { resultBody.querySelector('.extras-row').classList.add('hidden') } diff --git a/src/pytest_html/table.py b/src/pytest_html/table.py new file mode 100644 index 00000000..95f7fa50 --- /dev/null +++ b/src/pytest_html/table.py @@ -0,0 +1,59 @@ +import warnings + + +class Table: + def __init__(self): + self._html = {} + + @property + def html(self): + return self._html + + +class Html(Table): + def __init__(self): + super().__init__() + self.html.setdefault("html", []) + self._replace_log = False + + def __delitem__(self, key): + # This means the log should be removed + self._replace_log = True + + @property + def replace_log(self): + return self._replace_log + + def append(self, html): + self.html["html"].append(html) + + +class Cell(Table): + def insert(self, index, html): + # backwards-compat + if not isinstance(html, str): + if html.__module__.startswith("py."): + warnings.warn( + "The 'py' module is deprecated and support " + "will be removed in a future release.", + DeprecationWarning, + ) + html = str(html) + html = html.replace("col", "data-column-type") + self._html[index] = html + + def pop(self, *args): + warnings.warn( + "'pop' is deprecated and no longer supported.", + DeprecationWarning, + ) + + +class Header(Cell): + pass + + +class Row(Cell): + def __delitem__(self, key): + # This means the item should be removed + self._html = None