pytest-html/src/pytest_html/plugin.py

124 lines
3.6 KiB
Python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import pytest
from . import extras # noqa: F401
from .html_report import HTMLReport
def pytest_addhooks(pluginmanager):
from . import hooks
pluginmanager.add_hookspecs(hooks)
def pytest_addoption(parser):
group = parser.getgroup("terminal reporting")
group.addoption(
"--html",
action="store",
dest="htmlpath",
metavar="path",
default=None,
help="create html report file at given path.",
)
group.addoption(
"--self-contained-html",
action="store_true",
help="create a self-contained html file containing all "
"necessary styles, scripts, and images - this means "
"that the report may not render or function where CSP "
"restrictions are in place (see "
"https://developer.mozilla.org/docs/Web/Security/CSP)",
)
group.addoption(
"--css",
action="append",
metavar="path",
default=[],
help="append given css file content to report style file.",
)
parser.addini(
"render_collapsed",
type="bool",
default=False,
help="Open the report with all rows collapsed. Useful for very large reports",
)
parser.addini(
"max_asset_filename_length",
default=255,
help="set the maximum filename length for assets "
"attached to the html report.",
)
parser.addini(
"environment_table_redact_list",
type="linelist",
help="A list of regexes corresponding to environment "
"table variables whose values should be redacted from the report",
)
def pytest_configure(config):
htmlpath = config.getoption("htmlpath")
if htmlpath:
missing_css_files = []
for csspath in config.getoption("css"):
if not os.path.exists(csspath):
missing_css_files.append(csspath)
if missing_css_files:
oserror = (
f"Missing CSS file{'s' if len(missing_css_files) > 1 else ''}:"
f" {', '.join(missing_css_files)}"
)
raise OSError(oserror)
if not hasattr(config, "workerinput"):
# prevent opening htmlpath on worker nodes (xdist)
config._html = HTMLReport(htmlpath, config)
config._next_gen = nextgen.NextGenReport(config, Path("nextgendata.js"))
config.pluginmanager.register(config._html)
config.pluginmanager.register(config._next_gen)
def pytest_unconfigure(config):
html = getattr(config, "_html", None)
if html:
del config._html
config.pluginmanager.unregister(html)
next_gen = getattr(config, "_next_gen", None)
if next_gen:
del config._next_gen
config.pluginmanager.unregister(next_gen)
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
report = outcome.get_result()
if report.when == "call":
fixture_extras = getattr(item.config, "extras", [])
plugin_extras = getattr(report, "extra", [])
report.extra = fixture_extras + plugin_extras
@pytest.fixture
def extra(pytestconfig):
"""Add details to the HTML reports.
.. code-block:: python
import pytest_html
def test_foo(extra):
extra.append(pytest_html.extras.url("http://www.example.com/"))
"""
pytestconfig.extras = []
yield pytestconfig.extras
del pytestconfig.extras[:]