Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can not embed image on windows hosts using extra.png(image) #214

Closed
Uil2liv opened this issue Jul 2, 2019 · 7 comments · Fixed by #223
Closed

can not embed image on windows hosts using extra.png(image) #214

Uil2liv opened this issue Jul 2, 2019 · 7 comments · Fixed by #223

Comments

@Uil2liv
Copy link

Uil2liv commented Jul 2, 2019

On a windows host, we cannot add an image to a report using pytest_html.extras.png().
It returns the following error:

Testing started at 00:17 ...
C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\Scripts\python.exe "D:\Program Files\JetBrains\PyCharm Community Edition 2017.3.3\helpers\pycharm\_jb_pytest_runner.py" -- --html=report.html
Launching py.test with arguments --html=report.html in C:\Users\proto\PycharmProjects\pytest_html_extra_image

============================= test session starts =============================
platform win32 -- Python 3.6.4, pytest-5.0.0, py-1.8.0, pluggy-0.12.0
rootdir: C:\Users\proto\PycharmProjects\pytest_html_extra_image
plugins: html-1.21.1, metadata-1.8.0collected 1 item

tests\sample_test.py .
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\_pytest\main.py", line 213, in wrap_session
INTERNALERROR>     session.exitstatus = doit(config, session) or 0
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\_pytest\main.py", line 257, in _main
INTERNALERROR>     config.hook.pytest_runtestloop(session=session)
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\hooks.py", line 289, in __call__
INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\manager.py", line 87, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\manager.py", line 81, in <lambda>
INTERNALERROR>     firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\callers.py", line 208, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\callers.py", line 80, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\callers.py", line 187, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\_pytest\main.py", line 278, in pytest_runtestloop
INTERNALERROR>     item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\hooks.py", line 289, in __call__
INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\manager.py", line 87, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\manager.py", line 81, in <lambda>
INTERNALERROR>     firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\callers.py", line 208, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\callers.py", line 80, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\callers.py", line 187, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\_pytest\runner.py", line 72, in pytest_runtest_protocol
INTERNALERROR>     runtestprotocol(item, nextitem=nextitem)
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\_pytest\runner.py", line 87, in runtestprotocol
INTERNALERROR>     reports.append(call_and_report(item, "call", log))
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\_pytest\runner.py", line 171, in call_and_report
INTERNALERROR>     hook.pytest_runtest_logreport(report=report)
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\hooks.py", line 289, in __call__
INTERNALERROR>     return self._hookexec(self, self.get_hookimpls(), kwargs)
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\manager.py", line 87, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook, methods, kwargs)
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\manager.py", line 81, in <lambda>
INTERNALERROR>     firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\callers.py", line 208, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\callers.py", line 80, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "C:\Users\proto\PycharmProjects\pytest_html_extra_image\venv\lib\site-packages\pluggy\callers.py", line 187, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "c:\users\proto\pycharmprojects\pytest_html_extra_image\venv\lib\site-packages\pytest_html\plugin.py", line 509, in pytest_runtest_logreport
INTERNALERROR>     self.append_passed(report)
INTERNALERROR>   File "c:\users\proto\pycharmprojects\pytest_html_extra_image\venv\lib\site-packages\pytest_html\plugin.py", line 291, in append_passed
INTERNALERROR>     self._appendrow('Passed', report)
INTERNALERROR>   File "c:\users\proto\pycharmprojects\pytest_html_extra_image\venv\lib\site-packages\pytest_html\plugin.py", line 273, in _appendrow
INTERNALERROR>     result = self.TestResult(outcome, report, self.logfile, self.config)
INTERNALERROR>   File "c:\users\proto\pycharmprojects\pytest_html_extra_image\venv\lib\site-packages\pytest_html\plugin.py", line 119, in __init__
INTERNALERROR>     self.append_extra_html(extra, extra_index, test_index)
INTERNALERROR>   File "c:\users\proto\pycharmprojects\pytest_html_extra_image\venv\lib\site-packages\pytest_html\plugin.py", line 202, in append_extra_html
INTERNALERROR>     extra.get('extension'), 'wb')
INTERNALERROR>   File "c:\users\proto\pycharmprojects\pytest_html_extra_image\venv\lib\site-packages\pytest_html\plugin.py", line 169, in create_asset
INTERNALERROR>     with open(asset_path, mode, **kwargs) as f:
INTERNALERROR> OSError: [Errno 22] Invalid argument: 'C:\\Users\\proto\\PycharmProjects\\pytest_html_extra_image\\assets\\tests/sample_test.py::test00_bcfe5b9ea2948de983c2f4df731cb2e2.png'

========================== 1 passed in 12.62 seconds ==========================
Process finished with exit code 0

The behaviour is not observed on a Linux system
It might be due to:

  • the double colons in the filename (forbidden on windows)
  • the slash used to represent the test hierarchy

Here is a sample to reproduce the behaviour:
tests/conftest.py:

import pytest

@pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):
    pytest_html = item.config.pluginmanager.getplugin('html')
    outcome = yield
    report = outcome.get_result()
    extra = getattr(report, 'extra', [])

    extra.append(pytest_html.extras.png(item.module.screenshot))

    report.extra = extra

tests/sample_test.py

from selenium import webdriver


screenshot = None


def test():
    global screenshot
    driver = webdriver.Firefox()
    driver.get("https://docs.pytest.org/")

    screenshot = driver.find_element_by_tag_name("html").screenshot_as_base64

    driver.close()

then run:

pytest --html=report.html
@BeyondEvil
Copy link
Contributor

Thanks for reporting this! @Uil2liv

And thanks for the detailed repro stuff, that's great!

Now, I just need to source a windows machine so I can run it, haha.

Quick question:

.screenshot_as_base64

should be

.screenshot_as_base64()

Just a typo?

@Uil2liv
Copy link
Author

Uil2liv commented Jul 7, 2019

Hi,

Not a typo, it appears that WebElement.screenshot_as_base64 is a property (https://seleniumhq.github.io/selenium/docs/api/py/_modules/selenium/webdriver/remote/webelement.html#WebElement.screenshot_as_base64)

Uil2liv added a commit to Uil2liv/pytest-html that referenced this issue Jul 10, 2019
In new asset name:
- Strip leading and trailing spaces
- Replace inner spaces by underscores
- Replace double colons by hyphens
- Remove all characters except alphanums, underscores, hyphens, dots and slashes
- Adapt path to system
@EricDelaney
Copy link

Hit the same problem on windows, whenever you hit a test failure it wants to write out the results file and tries to create a file with the "::" in the file name which fails and the entire test run stops.

The change causing the problem occurred between between 1.20.0 and 1.21.0

@BeyondEvil
Copy link
Contributor

BeyondEvil commented Jul 10, 2019

I'm pretty sure this and #215 and #216 share the same root cause.

Hopefully I'll have some time tonight to check on this. I'm sorry it's taking a while to address properly. The excuse I have is that I don't own a windows machine - so I have to go through the wonderful and joyous task of setting up a windows VM with python...

I'm sure I'll manage, but if someone has a link to an article that will take me through it - please share. Because sharing is caring. ❤️

@BeyondEvil
Copy link
Contributor

@EricDelaney @Uil2liv

Again, sorry for the delay.

Would you mind testing out PR #223 and see if that solves the issues you've been seeing? Much appreciated!

@Uil2liv
Copy link
Author

Uil2liv commented Aug 5, 2019

@BeyondEvil
It seems OK for me with #223.
The reproduction example above gives me a well formed attachement in assets/tests_sample_test.py__test_0_0.png

Thanks for that fix 👍

@BeyondEvil
Copy link
Contributor

Awesome, thanks @Uil2liv !

BeyondEvil added a commit that referenced this issue Aug 6, 2019
* Fix assets file naming to work across both *nix and windows

Fixes #214
Fixes #213

* Better replacement strategy for test id

* Update markers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants