pytest-html
pytest-html copied to clipboard
binascii.Error if media file not present
Using pytest-html 3.1.1 and xdist 2.5.0
When passing a non existing file as media, pytest-html will raise an error during report generation.
To reproduce: Add extra.append(extras.image("doesnotexist")) in a report.
Actually I am looking for two things here
- binascii.Error should not happen. What encoding should the passed 'content' string have?
- How to reference local media, which does not yet exist as a file?
More details:
We are using 'extra.addImage()' in combination with pytest xdist. When generating the html report, the media files from the different testing engines are not yet rsynced, so pytest-html will not see most of the files during report generation.
Because of this, the check (plugin.py 406ff, version 3.1.1)
is_uri_or_path = content.startswith(("file", "http")) or isfile(content)
is False.
Subsequently, the 'content' is treated as an external link, and decoded with this:
content = b64decode(content.encode("utf-8"))
This causes an binascii.Error, and no html report is generated.
The error can be triggered easily by adding an invalid media,like
extra.append(extras.image("doesnotexist"))
to a report.
The quickfix for us was to always set is_uri_or_path True.
Media files are referenced locally, so prefixing the uri with "http" or "file" is a bit difficult.
What OS and python versions is this happening on?
The OS is Ubuntu 20.04 The version output from pytest: platform linux -- Python 3.9.7, pytest-7.0.1, pluggy-1.0.0 plugins: cov-3.0.0, instafail-0.4.2, html-3.1.1, xvfb-2.0.0, xdist-2.5.0, flaky-3.7.0, metadata-1.11.0, icdiff-0.5, forked-1.4.0
I think the b64decode is intended to decode inlined graphics, that are embedded in the html as b64 encoded data. Decoding a filename or uri will not work.
Out of curiosity, why do you want to reference a file that doesn't exist?
We are using xdist, and files are spread over several VMs. The html report is generated from the data xdist collected. But only after the tests are finished, we run rsync to copy all media files into the report directory. So, the media files will exist shortly after the report.html is generated.
We are using xdist, and files are spread over several VMs. The html report is generated from the data xdist collected. But only after the tests are finished, we run rsync to copy all media files into the report directory. So, the media files will exist shortly after the report.html is generated.
Ah I see.
You could check if the file exists before adding it to the report (extra.append(extras.image("doesnotexist")))
The best I can offer is to spit out a warning, but not error out.
The file will exist, it is just not yet there. As I have understood it by now, the solution could be to detect if content starts with a "/", so we can distinguish relative URIs from data URIs?
Yeah, we could detect that.
I'm thinking I'm might flip the logic here...
- Make a best effort check to see if the content is base64, if it is, write to assets folder.
- If relative path, turn into absolute path and just add it (make zero attempts to validate, that's up to the user to make sure it exists).
- If absolute path, prefixed with
fileorhttp, just add it (no validation).
Basically, not do any hand-holding - it's up to the user to make sure an image is where it's supposed to be when the report is rendered.
I think this should solve your issue. @KjellMorgenstern