Skip to content

Commit 51c77d5

Browse files
committed
Finish up the custom CSS support including docs and tests
1 parent f8fcd88 commit 51c77d5

3 files changed

Lines changed: 59 additions & 27 deletions

File tree

README.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,17 @@ The plugin will issue a warning when adding files or links to the standalone rep
7373
Enhancing reports
7474
-----------------
7575

76+
Appearance
77+
~~~~~~~~~~
78+
79+
Custom CSS (Cascasding Style Sheets) can be passed on the command line using
80+
the :code:`--css` option. These will be applied in the order specified, and can
81+
be used to change the appearance of the report.
82+
83+
.. code-block:: bash
84+
85+
$ pytest --html=report.html --css=highcontrast.css --css=accessible.css
86+
7687
Environment
7788
~~~~~~~~~~~
7889

pytest_html/plugin.py

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,19 @@ def pytest_addoption(parser):
5555
'that the report may not render or function where CSP '
5656
'restrictions are in place (see '
5757
'https://developer.mozilla.org/docs/Web/Security/CSP)')
58-
group.addoption('--append-css', action='append', dest='appendcss',
59-
metavar='path', default=None,
60-
help='append given CSS file content to report style file.')
58+
group.addoption('--css', action='append', metavar='path',
59+
help='append given css file content to report style file.')
6160

6261

6362
def pytest_configure(config):
64-
htmlpath = config.option.htmlpath
65-
# prevent opening htmlpath on slave nodes (xdist)
66-
if htmlpath and not hasattr(config, 'slaveinput'):
67-
config._html = HTMLReport(htmlpath, config)
68-
config.pluginmanager.register(config._html)
63+
htmlpath = config.getoption('htmlpath')
64+
if htmlpath:
65+
for csspath in config.getoption('css') or []:
66+
open(csspath)
67+
if not hasattr(config, 'slaveinput'):
68+
# prevent opening htmlpath on slave nodes (xdist)
69+
config._html = HTMLReport(htmlpath, config)
70+
config.pluginmanager.register(config._html)
6971

7072

7173
def pytest_unconfigure(config):
@@ -95,9 +97,6 @@ def __init__(self, logfile, config):
9597
self.self_contained = config.getoption('self_contained_html')
9698
self.config = config
9799

98-
self.css_append = config.getoption('appendcss')
99-
self.css_errors = []
100-
101100
class TestResult:
102101

103102
def __init__(self, outcome, report, logfile, config):
@@ -135,7 +134,8 @@ def __init__(self, outcome, report, logfile, config):
135134
if len(cells) > 0:
136135
self.row_table = html.tr(cells)
137136
self.row_extra = html.tr(html.td(self.additional_html,
138-
class_='extra', colspan=len(cells)))
137+
class_='extra',
138+
colspan=len(cells)))
139139

140140
def __lt__(self, other):
141141
order = ('Error', 'Failed', 'Rerun', 'XFailed',
@@ -328,19 +328,13 @@ def _generate_report(self, session):
328328
self.style_css += '\n'.join(ansi_css)
329329

330330
# <DF> Add user-provided CSS
331-
if self.css_append:
332-
self.style_css += '\n'
333-
user_css = []
334-
for filename in self.css_append:
335-
try:
336-
with open(filename, 'r') as css_file:
337-
user_css.append('/* Begin CSS from {} */'.format(filename))
338-
user_css.extend(css_file.readlines())
339-
user_css.append('/* End CSS from {} */'.format(filename))
340-
except Exception as e:
341-
self.css_errors.append('Warning: Could not read CSS from {}: {}'.format(filename, e))
342-
343-
self.style_css += '\n'.join(user_css)
331+
for path in self.config.getoption('css') or []:
332+
self.style_css += '\n/******************************'
333+
self.style_css += '\n * CUSTOM CSS'
334+
self.style_css += '\n * {}'.format(path)
335+
self.style_css += '\n ******************************/\n\n'
336+
with open(path, 'r') as f:
337+
self.style_css += f.read()
344338

345339
css_href = '{0}/{1}'.format('assets', 'style.css')
346340
html_css = html.link(href=css_href, rel='stylesheet',
@@ -522,5 +516,3 @@ def pytest_sessionfinish(self, session):
522516
def pytest_terminal_summary(self, terminalreporter):
523517
terminalreporter.write_sep('-', 'generated html file: {0}'.format(
524518
self.logfile))
525-
for css_error in self.css_errors:
526-
terminalreporter.write_line(css_error)

testing/test_pytest_html.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,3 +627,32 @@ def test_pass(): pass
627627
assert_results(html, tests=0, passed=0, errors=1)
628628
regex_error = '(Import|ModuleNotFound)Error: No module named .*xyz'
629629
assert re.search(regex_error, html) is not None
630+
631+
@pytest.mark.parametrize('colors', [(['red']), (['green', 'blue'])])
632+
def test_css(self, testdir, colors):
633+
testdir.makepyfile('def test_pass(): pass')
634+
css = {}
635+
cssargs = []
636+
for color in colors:
637+
style = '* {{color: {}}}'.format(color)
638+
path = testdir.makefile('.css', **{color: style})
639+
css[color] = {'style': style, 'path': path}
640+
cssargs.extend(['--css', path])
641+
result, html = run(testdir, 'report.html', '--self-contained-html',
642+
*cssargs)
643+
assert result.ret == 0
644+
for k, v in css.items():
645+
assert str(v['path']) in html
646+
assert v['style'] in html
647+
648+
def test_css_invalid(self, testdir):
649+
testdir.makepyfile('def test_pass(): pass')
650+
result = testdir.runpytest('--html', 'report.html',
651+
'--css', 'style.css')
652+
assert result.ret
653+
assert "No such file or directory: 'style.css'" in result.stderr.str()
654+
655+
def test_css_invalid_no_html(self, testdir):
656+
testdir.makepyfile('def test_pass(): pass')
657+
result = testdir.runpytest('--css', 'style.css')
658+
assert result.ret == 0

0 commit comments

Comments
 (0)