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