Finish up the custom CSS support including docs and tests

This commit is contained in:
Dave Hunt 2018-04-05 13:10:32 +01:00
parent f8fcd88c08
commit 51c77d5c3f
No known key found for this signature in database
GPG Key ID: EA962DBFE7ABAD7B
3 changed files with 59 additions and 27 deletions

View File

@ -73,6 +73,17 @@ The plugin will issue a warning when adding files or links to the standalone rep
Enhancing reports
-----------------
Appearance
~~~~~~~~~~
Custom CSS (Cascasding Style Sheets) can be passed on the command line using
the :code:`--css` option. These will be applied in the order specified, and can
be used to change the appearance of the report.
.. code-block:: bash
$ pytest --html=report.html --css=highcontrast.css --css=accessible.css
Environment
~~~~~~~~~~~

View File

@ -55,17 +55,19 @@ def pytest_addoption(parser):
'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('--append-css', action='append', dest='appendcss',
metavar='path', default=None,
help='append given CSS file content to report style file.')
group.addoption('--css', action='append', metavar='path',
help='append given css file content to report style file.')
def pytest_configure(config):
htmlpath = config.option.htmlpath
# prevent opening htmlpath on slave nodes (xdist)
if htmlpath and not hasattr(config, 'slaveinput'):
config._html = HTMLReport(htmlpath, config)
config.pluginmanager.register(config._html)
htmlpath = config.getoption('htmlpath')
if htmlpath:
for csspath in config.getoption('css') or []:
open(csspath)
if not hasattr(config, 'slaveinput'):
# prevent opening htmlpath on slave nodes (xdist)
config._html = HTMLReport(htmlpath, config)
config.pluginmanager.register(config._html)
def pytest_unconfigure(config):
@ -95,9 +97,6 @@ class HTMLReport(object):
self.self_contained = config.getoption('self_contained_html')
self.config = config
self.css_append = config.getoption('appendcss')
self.css_errors = []
class TestResult:
def __init__(self, outcome, report, logfile, config):
@ -135,7 +134,8 @@ class HTMLReport(object):
if len(cells) > 0:
self.row_table = html.tr(cells)
self.row_extra = html.tr(html.td(self.additional_html,
class_='extra', colspan=len(cells)))
class_='extra',
colspan=len(cells)))
def __lt__(self, other):
order = ('Error', 'Failed', 'Rerun', 'XFailed',
@ -328,19 +328,13 @@ class HTMLReport(object):
self.style_css += '\n'.join(ansi_css)
# <DF> Add user-provided CSS
if self.css_append:
self.style_css += '\n'
user_css = []
for filename in self.css_append:
try:
with open(filename, 'r') as css_file:
user_css.append('/* Begin CSS from {} */'.format(filename))
user_css.extend(css_file.readlines())
user_css.append('/* End CSS from {} */'.format(filename))
except Exception as e:
self.css_errors.append('Warning: Could not read CSS from {}: {}'.format(filename, e))
self.style_css += '\n'.join(user_css)
for path in self.config.getoption('css') or []:
self.style_css += '\n/******************************'
self.style_css += '\n * CUSTOM CSS'
self.style_css += '\n * {}'.format(path)
self.style_css += '\n ******************************/\n\n'
with open(path, 'r') as f:
self.style_css += f.read()
css_href = '{0}/{1}'.format('assets', 'style.css')
html_css = html.link(href=css_href, rel='stylesheet',
@ -522,5 +516,3 @@ class HTMLReport(object):
def pytest_terminal_summary(self, terminalreporter):
terminalreporter.write_sep('-', 'generated html file: {0}'.format(
self.logfile))
for css_error in self.css_errors:
terminalreporter.write_line(css_error)

View File

@ -627,3 +627,32 @@ class TestHTML:
assert_results(html, tests=0, passed=0, errors=1)
regex_error = '(Import|ModuleNotFound)Error: No module named .*xyz'
assert re.search(regex_error, html) is not None
@pytest.mark.parametrize('colors', [(['red']), (['green', 'blue'])])
def test_css(self, testdir, colors):
testdir.makepyfile('def test_pass(): pass')
css = {}
cssargs = []
for color in colors:
style = '* {{color: {}}}'.format(color)
path = testdir.makefile('.css', **{color: style})
css[color] = {'style': style, 'path': path}
cssargs.extend(['--css', path])
result, html = run(testdir, 'report.html', '--self-contained-html',
*cssargs)
assert result.ret == 0
for k, v in css.items():
assert str(v['path']) in html
assert v['style'] in html
def test_css_invalid(self, testdir):
testdir.makepyfile('def test_pass(): pass')
result = testdir.runpytest('--html', 'report.html',
'--css', 'style.css')
assert result.ret
assert "No such file or directory: 'style.css'" in result.stderr.str()
def test_css_invalid_no_html(self, testdir):
testdir.makepyfile('def test_pass(): pass')
result = testdir.runpytest('--css', 'style.css')
assert result.ret == 0