pytest-html icon indicating copy to clipboard operation
pytest-html copied to clipboard

binascii.Error if media file not present

Open KjellMorgenstern opened this issue 3 years ago • 8 comments
trafficstars

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

  1. binascii.Error should not happen. What encoding should the passed 'content' string have?
  2. 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.

KjellMorgenstern avatar Mar 22 '22 12:03 KjellMorgenstern

What OS and python versions is this happening on?

BeyondEvil avatar Mar 27 '22 00:03 BeyondEvil

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

KjellMorgenstern avatar Mar 27 '22 08:03 KjellMorgenstern

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.

KjellMorgenstern avatar Mar 27 '22 09:03 KjellMorgenstern

Out of curiosity, why do you want to reference a file that doesn't exist?

BeyondEvil avatar Mar 27 '22 13:03 BeyondEvil

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.

KjellMorgenstern avatar Mar 27 '22 14:03 KjellMorgenstern

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.

BeyondEvil avatar Mar 28 '22 00:03 BeyondEvil

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?

KjellMorgenstern avatar Mar 28 '22 05:03 KjellMorgenstern

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 file or http, 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

BeyondEvil avatar Jul 11 '22 23:07 BeyondEvil