Error in Adding ScreenShot to Pytest Html Report - python

I'm unable to add Screen-Shot of failed Scanerios in desired html report.
What I did is just moved creation of html report in other desired folder and i'm getting error that Screen Shot is not getting placed in HTML report
below is my code for ScreenShot present in conftest
#pytest.mark.hookwrapper
def pytest_runtest_makereport(item):
"""
Extends the PyTest Plugin to take and embed screenshot in html report, whenever test fails.
:param item:
"""
pytest_html = item.config.pluginmanager.getplugin('html')
outcome = yield
report = outcome.get_result()
extra = getattr(report, 'extra', [])
if report.when == 'call' or report.when == "setup":
xfail = hasattr(report, 'wasxfail')
if (report.skipped and xfail) or (report.failed and not xfail):
file_name = report.nodeid.replace("::", "_") + ".png"
_capture_screenshot(file_name)
if file_name:
html = '<div><img src="%s" alt="screenshot" style="width:304px;height:228px;" ' \
'onclick="window.open(this.src)" align="right"/></div>' % file_name
extra.append(pytest_html.extras.html(html))
report.extra = extra
def _capture_screenshot(name):
driver.get_screenshot_as_file(name)

Related

How to save screenshots including test results, etc. when the test is finished in pytest

I want to save a screenshot when a test fails.
However, the screenshot name must include the information used in the test.
example
-> Currently my code is able to send the city I used in the test.
However, it does not operate according to success or failure.
How can I make the test receive a variable as well and act on success/failure?
(The file name I want: {city}{id}{pass/fail}.png
paris_testaccount01_pass.png)
test_example.py
class TesExample(BaseTest):
def test_example(self, capture_screenshot):
city = "paris"
id = "testaccount01"
# ~~ Skip test content ~~
capture_screenshot(self.driver, city)
BaseTest.py
import pytest
#pytest.mark.usefixtures("get_browser")
class BaseTest:
pass
conftest.py
#pytest.fixture()
def capture_screenshot():
def _capture_screenshot(get_browser, name):
driver = get_browser
driver.get_screenshot_as_file(f'../Screenshots/{name}.png')
return _capture_screenshot
return _capture_screenshot
If you use pytest-html for reporting and If you would take screenshot in case of fail, you can use following code in your conftest:
#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', [])
if report.when == 'call':
xfail_state = hasattr(report, 'wasxfail')
if (report.skipped and xfail_state) or (report.failed and not xfail_state):
mydriver = item.funcargs['driver']
screenshot = mydriver.get_screenshot_as_base64()
extra.append(pytest_html.extras.image(screenshot, ''))
report.extra = extra

Screenshot is not getting generated on test failure even if the code for taking screenshot is correct in Selenium Python

I have attached a hook for taking screenshot whenever it encounters a failure and it will attach the screenshot to the report. But, on failure, the screenshot is not getting generated and on clicking the screenshot, the error is coming as 'Your file couldn’t be accessed. It may have been moved, edited, or deleted.
ERR_FILE_NOT_FOUND'
Attaching the hook which was able to capture screenshot successfully. But, now it is not getting generated.
#pytest.mark.hookwrapper
def pytest_runtest_makereport(item):
"""
Extends the PyTest Plugin to take and embed screenshot in html report, whenever test fails.
:param item:
"""
pytest_html = item.config.pluginmanager.getplugin('html')
outcome = yield
report = outcome.get_result()
extra = getattr(report, 'extra', [])
if report.when == 'call' or report.when == "setup":
xfail = hasattr(report, 'wasxfail')
if (report.skipped and xfail) or (report.failed and not xfail):
file_name = report.nodeid.replace("::", "_") + ".png"
_capture_screenshot(file_name)
if file_name:
html = '<div><img src="%s" alt="screenshot" style="width:304px;height:228px;" ' \
'onclick="window.open(this.src)" align="right"/></div>' % file_name
extra.append(pytest_html.extras.html(html))
report.extra = extra
def _capture_screenshot(name):
driver.get_screenshot_as_file(name)
You did not add the path from where to take the screenshots I use something like this:
def remove_files():
download_path = r'E:\iollo\food-generation-ocb-automation-a36cc1ff0a57\scrennshot\**\*.png'
return download_path
Here I add a path to downloaded the screenshots in a folder and than I use the fixture to add the path in the report.
#pytest.hookimpl(hookwrapper=True)
#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', [])
if report.when == 'call':
feature_request = item.funcargs['request']
xfail = hasattr(report, "wasxfail")
if (report.skipped and xfail) or (report.failed and not xfail):
feature_request = item.funcargs["request"]
driver = feature_request.getfixturevalue("setup")
timestamp = datetime.now().strftime('%H-%M-%S')
path = "/oalaCuBunatati"
ismount= os.path.ismount(path)
img_name = "name" + timestamp + ".png"
# img_path = os.path.join("D:\GIT\ocb-automation\scrennshot", img_name)
img_path = os.path.join(r'/oalaCuBunatati/scrennshot', img_name)
driver.save_screenshot(img_path)
if (report.skipped and xfail) or (report.failed and not xfail):
# only add additional html on failure
extra.append(pytest_html.extras.image(img_path))
extra.append(pytest_html.extras.html('<div>Additional HTML</div>'))
report.extra = extra
Maybe this will help you, in this way I use to generate the screenshots into html

Pytest html report customization - add new column in report

I need help regarding pytest html report customization. I need to print failed network request status code(By TestCase wise) in report so I did the below code. StatusCode column created successfully but not getting data in html report. also, test case-wise statuscode row does not appear in the report.
Conftest.py
#pytest.mark.optionalhook
def pytest_html_results_table_header(cells):
cells.append(html.th('Statuscode'))
#pytest.mark.optionalhook
def pytest_html_result_table_row(report,cells):
cells.append(html.td(report.statuscode))
def pytest_runtest_makereport(item):
"""
Extends the PyTest Plugin to take and embed screenshot in html report, whenever test fails.
:param item:
"""
pytest_html = item.config.pluginmanager.getplugin('html')
outcome = yield
report = outcome.get_result()
setattr(report, "duration_formatter", "%H:%M:%S.%f")
extra = getattr(report, 'extra', [])
statuscode = []
if report.when == 'call' or report.when == "setup":
xfail = hasattr(report, 'wasxfail')
if (report.skipped and xfail) or (report.failed and not xfail):
file_name = report.nodeid.replace("::", "_")+".png"
_capture_screenshot(file_name)
if file_name:
html = '<div><img src="%s" alt="screenshot" style="width:304px;height:228px;" ' \
'onclick="window.open(this.src)" align="right"/></div>' % file_name
extra.append(pytest_html.extras.html(html))
for request in driver.requests:
if url in request.url and request.response.status_code >=400 and request.response.status_code <= 512:
statuscode.append(request.response.status_code)
print("*********Status codes************",statuscode)
report.statuscode=statuscode
report.extra = extra

pytest html - pass images to the hook in conftest.py from a test file

I have a test that produce a HTML output via pytest-html.
I get the report, but I would like to add a reference to the failure and to the expected image; I save those in my main test.py file, and I added the hook to conftest.py.
Now, I have no idea how to pass those images to the function; the hook is called after the test is performed; and currently I am hardcoding the output files and they are attached; but I would like to pass the path to the image from the test instead, especially because I need to write more tests that may be saved somewhere else from my usual folder, and may have different names.
This is the hook I have in conftest.py
#pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):
timestamp = datetime.now().strftime('%H-%M-%S')
pytest_html = item.config.pluginmanager.getplugin('html')
outcome = yield
report = outcome.get_result()
extra = getattr(report, 'extra', [])
if report.when == 'call':
# Attach failure image, hardcoded...how do I pass this from the test?
extra.append(pytest_html.extras.image('/tmp/image1.png'))
# test report html
extra.append(pytest_html.extras.url('http://www.theoutput.com/'))
xfail = hasattr(report, 'wasxfail')
if (report.skipped and xfail) or (report.failed and not xfail):
# only add additional data on failure
# Same as above, hardcoded but I want to pass the reference image from the test
extra.append(pytest_html.extras.image('/tmp/image2.png'))
extra.append(pytest_html.extras.html('<div>Additional HTML</div>'))
report.extra = extra
How can I pass to the hook, a variable containing the path of the image(s) to attach, from my pytest test files?
I found a workaround, although it is not pretty.
Adding a variable at module level in my test file, allow me to use item.module.varname, so if I set varname in my module test, and then assign it in the test; I can access it in pytest_runtest_makereport
in testfile.py
import pytest
myvar1 = None
myvar2 = None
class VariousTests(unittest.TestCase):
def test_attachimages():
global myvar1
global myvar2
myvar1 = "/tmp/img1.png"
myvar2 = "/tmp/img2.png"
in conftest.py
#pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):
timestamp = datetime.now().strftime('%H-%M-%S')
pytest_html = item.config.pluginmanager.getplugin('html')
outcome = yield
report = outcome.get_result()
extra = getattr(report, 'extra', [])
if report.when == 'call':
# Attach failure image
img1 = item.module.myvar1
img2 = item.module.myvar2
extra.append(pytest_html.extras.png(img1))
# test report html
extra.append(pytest_html.extras.url('http://www.theoutput.com/'))
xfail = hasattr(report, 'wasxfail')
if (report.skipped and xfail) or (report.failed and not xfail):
# only add additional data on failure
# Same as above, hardcoded but I want to pass the reference image from the test
extra.append(pytest_html.extras.png(img2))
extra.append(pytest_html.extras.html('<div>Additional HTML</div>'))
report.extra = extra

Pytest-html Customization

I am using pytest-html plugin for report generation for my test cases. I want to add a line item if the script fails. So here's my code---
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', [])
if report.when == 'call':
# always add url to report
extra.append(pytest_html.extras.url('http://www.example.com/'))
xfail = hasattr(report, 'wasxfail')
if (report.skipped and xfail) or (report.failed and not xfail):
# only add additional html on failure
extra.append(pytest_html.extras.html('<div>Additional HTML</div>'))
report.extra = extra
def test_sayHello():
assert False, "I mean for this to fail"
print "hello"
def test_sayBye():
print "Bye"
I am running the scipt using -
pytest --html=report.html
I can see the report getting generatesd but it doesnt have a line item as Additional HTML.
Also is there a way via which I can add such line items in between of my scripts to the report.
Really appreciate help.
This should work:
#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', [])
if report.when == 'call':
extra.append(pytest_html.extras.html('<p>some html</p>'))
report.extra = extra

Categories

Resources