Added the CSS specification for the video class. It is pretty much a duplicate of the image css.
Code for the video extra has been extracted to a function to clean up a bit the if/elif/elif that is starting to get pretty big. Maybe the other conditions could be extracted to their own method to clean up a bit. Once again, there seems to be a lot of code duplication with image, so we may want to refactor images, videos, and audio as a media type and have some kind of template method. Basic unit tests were added to make sure that the extra was correctly added to the report when the extra was requested.
This commit is contained in:
parent
8de28f6d1f
commit
f03b9d9a4b
|
@ -236,38 +236,7 @@ class HTMLReport:
|
|||
href = extra.get("content")
|
||||
|
||||
elif extra.get("format") == extras.FORMAT_VIDEO:
|
||||
video_base = (
|
||||
'<video controls>\n<source src={} type="video/mp4">\n</video>'
|
||||
)
|
||||
content = extra.get("content")
|
||||
try:
|
||||
is_uri_or_path = content.startswith(("file", "http")) or isfile(
|
||||
content
|
||||
)
|
||||
except ValueError:
|
||||
# On Windows, os.path.isfile throws this exception when
|
||||
# passed a b64 encoded image.
|
||||
is_uri_or_path = False
|
||||
if is_uri_or_path:
|
||||
if self.self_contained:
|
||||
warnings.warn(
|
||||
"Self-contained HTML report "
|
||||
"includes link to external "
|
||||
"resource: {}".format(content)
|
||||
)
|
||||
|
||||
html_div = html.div(raw(video_base.format(extra.get("content"))))
|
||||
elif self.self_contained:
|
||||
src = "data:{};base64,{}".format(extra.get("mime_type"), content)
|
||||
html_div = html.div(raw(video_base.format(src)))
|
||||
else:
|
||||
content = b64decode(content.encode("utf-8"))
|
||||
href = src = self.create_asset(
|
||||
content, extra_index, test_index, extra.get("extension"), "wb"
|
||||
)
|
||||
|
||||
html_div = html.a(video_base.format(src), href=href)
|
||||
self.additional_html.append(html.div(html_div, class_="video"))
|
||||
self._append_video(extra, extra_index, test_index)
|
||||
|
||||
if href is not None:
|
||||
self.links_html.append(
|
||||
|
@ -310,6 +279,36 @@ class HTMLReport:
|
|||
log.append("No log output captured.")
|
||||
additional_html.append(log)
|
||||
|
||||
def _append_video(self, extra, extra_index, test_index):
|
||||
video_base = '<video controls><source src="{}" type="video/mp4"></video>'
|
||||
content = extra.get("content")
|
||||
try:
|
||||
is_uri_or_path = content.startswith(("file", "http")) or isfile(content)
|
||||
except ValueError:
|
||||
# On Windows, os.path.isfile throws this exception when
|
||||
# passed a b64 encoded image.
|
||||
is_uri_or_path = False
|
||||
if is_uri_or_path:
|
||||
if self.self_contained:
|
||||
warnings.warn(
|
||||
"Self-contained HTML report "
|
||||
"includes link to external "
|
||||
"resource: {}".format(content)
|
||||
)
|
||||
|
||||
html_div = html.div(raw(video_base.format(extra.get("content"))))
|
||||
elif self.self_contained:
|
||||
src = "data:{};base64,{}".format(extra.get("mime_type"), content)
|
||||
html_div = html.div(raw(video_base.format(src)))
|
||||
else:
|
||||
content = b64decode(content.encode("utf-8"))
|
||||
href = src = self.create_asset(
|
||||
content, extra_index, test_index, extra.get("extension"), "wb"
|
||||
)
|
||||
|
||||
html_div = html.a(video_base.format(src), href=href)
|
||||
self.additional_html.append(html.div(html_div, class_="video"))
|
||||
|
||||
def _appendrow(self, outcome, report):
|
||||
result = self.TestResult(outcome, report, self.logfile, self.config)
|
||||
if result.row_table is not None:
|
||||
|
|
|
@ -113,6 +113,19 @@ div.image {
|
|||
div.image img {
|
||||
width: 320px
|
||||
}
|
||||
div.video {
|
||||
border: 1px solid #e6e6e6;
|
||||
float: right;
|
||||
height: 240px;
|
||||
margin-left: 5px;
|
||||
overflow: hidden;
|
||||
width: 320px
|
||||
}
|
||||
div.video video {
|
||||
overflow: hidden;
|
||||
width: 320px;
|
||||
height: 240px;
|
||||
}
|
||||
.collapsed {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -418,6 +418,37 @@ class TestHTML:
|
|||
self.test_extra_image(testdir, "image/png", "png")
|
||||
assert mock_isfile.call_count == 1
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"mime_type, extension", [("video/mp4", "mp4")],
|
||||
)
|
||||
def test_extra_video(self, testdir, mime_type, extension):
|
||||
content = str(random.random())
|
||||
testdir.makeconftest(
|
||||
f"""
|
||||
import pytest
|
||||
@pytest.hookimpl(hookwrapper=True)
|
||||
def pytest_runtest_makereport(item, call):
|
||||
outcome = yield
|
||||
report = outcome.get_result()
|
||||
if report.when == 'call':
|
||||
from pytest_html import extras
|
||||
report.extra = [extras.{extension}('{content}')]
|
||||
"""
|
||||
)
|
||||
testdir.makepyfile("def test_pass(): pass")
|
||||
result, html = run(testdir, "report.html", "--self-contained-html")
|
||||
assert result.ret == 0
|
||||
src = f"data:{mime_type};base64,{content}"
|
||||
assert (
|
||||
f'<video controls><source src="{src}" type="{mime_type}"></video>' in html
|
||||
)
|
||||
|
||||
def test_extra_video_windows(self, mocker, testdir):
|
||||
mock_isfile = mocker.patch("pytest_html.plugin.isfile")
|
||||
mock_isfile.side_effect = ValueError("stat: path too long for Windows")
|
||||
self.test_extra_video(testdir, "video/mp4", "mp4")
|
||||
assert mock_isfile.call_count == 1
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"content", [("u'\u0081'"), ("'foo'"), ("b'\\xe2\\x80\\x93'")]
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue