From 69a4cdac18b81d016554d814efc4fb69f16a9847 Mon Sep 17 00:00:00 2001 From: Andreas Pelme Date: Wed, 5 Oct 2016 13:00:34 +0200 Subject: [PATCH 1/8] Failing test for non-session scoped screenshots --- tests/test_plugin.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/test_plugin.py b/tests/test_plugin.py index e46ec56..e03f527 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -177,6 +177,29 @@ def test_screenshot(simple_page, browser): assert testdir.tmpdir.join('test_browser_screenshot_normal', 'test_screenshot-browser.png') +def test_browser_screenshot_function_scoped_browser(testdir, simple_page_content): + """Test making screenshots on test failure. + + Normal test run. + """ + testdir.inline_runsource(""" + import pytest + + @pytest.fixture + def simple_page(httpserver, browser): + httpserver.serve_content( + '''{0}''', code=200, headers={{'Content-Type': 'text/html'}}) + browser.visit(httpserver.url) + + def test_screenshot(simple_page, browser): + assert False + """.format(simple_page_content), "-vl", "-r w", '--splinter-session-scoped-browser=false') + + content = testdir.tmpdir.join('test_browser_screenshot_function_scoped_browser', 'test_screenshot-browser.html').read() + assert content.replace('\n', '') == simple_page_content.replace('\n', '') + assert testdir.tmpdir.join('test_browser_screenshot_normal', 'test_screenshot-browser.png') + + def test_browser_screenshot_escaped(testdir, simple_page_content): """Test making screenshots on test failure with escaped test names. From 2253fa58282226f4a06865a545058cc3eb8206b1 Mon Sep 17 00:00:00 2001 From: Andreas Pelme Date: Wed, 5 Oct 2016 13:33:43 +0200 Subject: [PATCH 2/8] Ensure that the browser is available before taking screenshots. This commit moves the screenshot handling from the `browser_screenshot` autouse fixture into `browser_instance_getter` which is the proper place for per-function teardown. This fixes issue #74. --- pytest_splinter/plugin.py | 122 +++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 62 deletions(-) diff --git a/pytest_splinter/plugin.py b/pytest_splinter/plugin.py index 3cf8317..f60c0b0 100644 --- a/pytest_splinter/plugin.py +++ b/pytest_splinter/plugin.py @@ -358,6 +358,9 @@ def browser_instance_getter( splinter_window_size, splinter_browser_class, splinter_clean_cookies_urls, + splinter_screenshot_getter_html, + splinter_screenshot_getter_png, + splinter_screenshot_encoding, session_tmpdir, browser_pool, ): @@ -386,6 +389,57 @@ def get_browser(splinter_webdriver, retry_count=3): else: raise + def take_screenshot(request, parent, browser_instance): + name = parent.__name__ + + if splinter_make_screenshot_on_failure and request.node.splinter_failure: + slaveoutput = getattr(request.config, 'slaveoutput', None) + try: + names = junitxml.mangle_testnames(request.node.nodeid.split("::")) + except AttributeError: + # pytest>=2.9.0 + names = junitxml.mangle_test_address(request.node.nodeid) + + classname = '.'.join(names[:-1]) + screenshot_dir = os.path.join(splinter_screenshot_dir, classname) + screenshot_file_name_format = '{0}.{{format}}'.format( + '{0}-{1}'.format(names[-1][:128 - len(name) - 5], name).replace(os.path.sep, '-') + ) + screenshot_file_name = screenshot_file_name_format.format(format='png') + screenshot_html_file_name = screenshot_file_name_format.format(format='html') + if not slaveoutput: + if not os.path.exists(screenshot_dir): + os.makedirs(screenshot_dir) + else: + screenshot_dir = session_tmpdir.ensure('screenshots', dir=True).strpath + screenshot_png_path = os.path.join(screenshot_dir, screenshot_file_name) + screenshot_html_path = os.path.join(screenshot_dir, screenshot_html_file_name) + LOGGER.info('Saving screenshot to %s', screenshot_dir) + try: + splinter_screenshot_getter_html(browser_instance, screenshot_html_path) + splinter_screenshot_getter_png(browser_instance, screenshot_png_path) + if request.node.splinter_failure.longrepr: + reprtraceback = request.node.splinter_failure.longrepr.reprtraceback + reprtraceback.extraline = _screenshot_extraline(screenshot_png_path, screenshot_html_path) + if slaveoutput is not None: + with codecs.open(screenshot_html_path, encoding=splinter_screenshot_encoding) as html_fd: + with open(screenshot_png_path) as fd: + slaveoutput.setdefault('screenshots', []).append({ + 'class_name': classname, + 'files': [ + { + 'file_name': screenshot_file_name, + 'content': fd.read(), + }, + { + 'file_name': screenshot_html_file_name, + 'content': html_fd.read(), + 'encoding': splinter_screenshot_encoding + }] + }) + except Exception as e: # NOQA + request.config.warn('SPL504', "Could not save screenshot: {0}".format(e)) + def prepare_browser(request, parent): splinter_webdriver = request.getfuncargvalue('splinter_webdriver') splinter_session_scoped_browser = request.getfuncargvalue('splinter_session_scoped_browser') @@ -398,6 +452,12 @@ def prepare_browser(request, parent): request.addfinalizer(browser.quit) elif not browser: browser = browser_pool[browser_key] = get_browser(splinter_webdriver) + request.addfinalizer(functools.partial( + take_screenshot, + request=request, + parent=parent, + browser_instance=browser, + )) try: if splinter_webdriver not in browser.driver_name.lower(): raise IOError('webdriver does not match') @@ -430,68 +490,6 @@ def prepare_browser(request, parent): return prepare_browser -@pytest.yield_fixture(autouse=True) -def browser_screenshot( - request, splinter_screenshot_dir, session_tmpdir, splinter_make_screenshot_on_failure, - splinter_screenshot_encoding, splinter_screenshot_getter_png, splinter_screenshot_getter_html): - """Make browser screenshot on test failure.""" - yield - for name, value in ( - # pytest 3 - getattr(request, '_fixture_values', {}) or - # pytest 2 - getattr(request, '_funcargs', {})).items(): - if hasattr(value, '__splinter_browser__'): - browser = value - if splinter_make_screenshot_on_failure and request.node.splinter_failure: - slaveoutput = getattr(request.config, 'slaveoutput', None) - try: - names = junitxml.mangle_testnames(request.node.nodeid.split("::")) - except AttributeError: - # pytest>=2.9.0 - names = junitxml.mangle_test_address(request.node.nodeid) - - classname = '.'.join(names[:-1]) - screenshot_dir = os.path.join(splinter_screenshot_dir, classname) - screenshot_file_name_format = '{0}.{{format}}'.format( - '{0}-{1}'.format(names[-1][:128 - len(name) - 5], name).replace(os.path.sep, '-') - ) - screenshot_file_name = screenshot_file_name_format.format(format='png') - screenshot_html_file_name = screenshot_file_name_format.format(format='html') - if not slaveoutput: - if not os.path.exists(screenshot_dir): - os.makedirs(screenshot_dir) - else: - screenshot_dir = session_tmpdir.ensure('screenshots', dir=True).strpath - screenshot_png_path = os.path.join(screenshot_dir, screenshot_file_name) - screenshot_html_path = os.path.join(screenshot_dir, screenshot_html_file_name) - LOGGER.info('Saving screenshot to %s', screenshot_dir) - try: - splinter_screenshot_getter_html(browser, screenshot_html_path) - splinter_screenshot_getter_png(browser, screenshot_png_path) - if request.node.splinter_failure.longrepr: - reprtraceback = request.node.splinter_failure.longrepr.reprtraceback - reprtraceback.extraline = _screenshot_extraline(screenshot_png_path, screenshot_html_path) - if slaveoutput is not None: - with codecs.open(screenshot_html_path, encoding=splinter_screenshot_encoding) as html_fd: - with open(screenshot_png_path) as fd: - slaveoutput.setdefault('screenshots', []).append({ - 'class_name': classname, - 'files': [ - { - 'file_name': screenshot_file_name, - 'content': fd.read(), - }, - { - 'file_name': screenshot_html_file_name, - 'content': html_fd.read(), - 'encoding': splinter_screenshot_encoding - }] - }) - except Exception as e: # NOQA - request.config.warn('SPL504', "Could not save screenshot: {0}".format(e)) - - @pytest.hookimpl(hookwrapper=True) def pytest_runtest_makereport(item, call): """Assign the report to the item for futher usage.""" From 0c34083b51d2c4428a4115c1144bcf1d66ec9733 Mon Sep 17 00:00:00 2001 From: Andreas Pelme Date: Tue, 1 Nov 2016 17:12:14 +0100 Subject: [PATCH 3/8] Fix too long line --- tests/test_plugin.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_plugin.py b/tests/test_plugin.py index e03f527..8ae3169 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -195,7 +195,10 @@ def test_screenshot(simple_page, browser): assert False """.format(simple_page_content), "-vl", "-r w", '--splinter-session-scoped-browser=false') - content = testdir.tmpdir.join('test_browser_screenshot_function_scoped_browser', 'test_screenshot-browser.html').read() + content = testdir.tmpdir.join( + 'test_browser_screenshot_function_scoped_browser', + 'test_screenshot-browser.html' + ).read() assert content.replace('\n', '') == simple_page_content.replace('\n', '') assert testdir.tmpdir.join('test_browser_screenshot_normal', 'test_screenshot-browser.png') From 52e10101bfb2a0591ef2247c53680e10efc0513a Mon Sep 17 00:00:00 2001 From: Andreas Pelme Date: Tue, 1 Nov 2016 17:19:25 +0100 Subject: [PATCH 4/8] Avoid crash when splinter_failure does not exist --- pytest_splinter/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytest_splinter/plugin.py b/pytest_splinter/plugin.py index f60c0b0..4da13be 100644 --- a/pytest_splinter/plugin.py +++ b/pytest_splinter/plugin.py @@ -392,7 +392,7 @@ def get_browser(splinter_webdriver, retry_count=3): def take_screenshot(request, parent, browser_instance): name = parent.__name__ - if splinter_make_screenshot_on_failure and request.node.splinter_failure: + if splinter_make_screenshot_on_failure and getattr(request.node, 'splinter_failure', False): slaveoutput = getattr(request.config, 'slaveoutput', None) try: names = junitxml.mangle_testnames(request.node.nodeid.split("::")) From a0b6503445012ddec717ac2488394d6f303bf02a Mon Sep 17 00:00:00 2001 From: Andreas Pelme Date: Wed, 2 Nov 2016 09:27:54 +0100 Subject: [PATCH 5/8] Make screenshot HTML assertion less sensitive. Firefox sometimes adds a hidden ') + assert '
' in content + assert 'text' in content + assert content.endswith('') + + def test_browser_screenshot_normal(testdir, simple_page_content): """Test making screenshots on test failure. @@ -172,9 +180,9 @@ def test_screenshot(simple_page, browser): assert False """.format(simple_page_content), "-vl", "-r w") - content = testdir.tmpdir.join('test_browser_screenshot_normal', 'test_screenshot-browser.html').read() - assert content.replace('\n', '') == simple_page_content.replace('\n', '') assert testdir.tmpdir.join('test_browser_screenshot_normal', 'test_screenshot-browser.png') + content = testdir.tmpdir.join('test_browser_screenshot_normal', 'test_screenshot-browser.html').read() + assert_valid_html_screenshot_content(content) def test_browser_screenshot_function_scoped_browser(testdir, simple_page_content): @@ -199,7 +207,8 @@ def test_screenshot(simple_page, browser): 'test_browser_screenshot_function_scoped_browser', 'test_screenshot-browser.html' ).read() - assert content.replace('\n', '') == simple_page_content.replace('\n', '') + + assert_valid_html_screenshot_content(content) assert testdir.tmpdir.join('test_browser_screenshot_normal', 'test_screenshot-browser.png') @@ -224,5 +233,5 @@ def test_screenshot(simple_page, browser, param): content = testdir.tmpdir.join( 'test_browser_screenshot_escaped', 'test_screenshot[escaped-param]-browser.html').read() - assert content.replace('\n', '') == simple_page_content.replace('\n', '') + assert_valid_html_screenshot_content(content) assert testdir.tmpdir.join('test_browser_screenshot_escaped', 'test_screenshot[escaped-param]-browser.png') From 21de5e4ff1c2186ecb7245b5be14d682171ec552 Mon Sep 17 00:00:00 2001 From: Andreas Pelme Date: Wed, 2 Nov 2016 09:31:45 +0100 Subject: [PATCH 6/8] Re-organize screenshot-taking code to be called at the correct time for both function and session scoped browsers. --- pytest_splinter/plugin.py | 165 +++++++++++++++++++++++++------------- 1 file changed, 108 insertions(+), 57 deletions(-) diff --git a/pytest_splinter/plugin.py b/pytest_splinter/plugin.py index 4da13be..f1014bf 100644 --- a/pytest_splinter/plugin.py +++ b/pytest_splinter/plugin.py @@ -336,6 +336,101 @@ def splinter_clean_cookies_urls(): return [] +def _take_screenshot( + request, + browser_instance, + fixture_name, + splinter_make_screenshot_on_failure, + splinter_screenshot_dir, + splinter_screenshot_getter_html, + splinter_screenshot_getter_png +): + + if splinter_make_screenshot_on_failure and request.node.splinter_failure: + slaveoutput = getattr(request.config, 'slaveoutput', None) + try: + names = junitxml.mangle_testnames(request.node.nodeid.split("::")) + except AttributeError: + # pytest>=2.9.0 + names = junitxml.mangle_test_address(request.node.nodeid) + + classname = '.'.join(names[:-1]) + screenshot_dir = os.path.join(splinter_screenshot_dir, classname) + screenshot_file_name_format = '{0}.{{format}}'.format( + '{0}-{1}'.format(names[-1][:128 - len(fixture_name) - 5], fixture_name).replace(os.path.sep, '-') + ) + screenshot_file_name = screenshot_file_name_format.format(format='png') + screenshot_html_file_name = screenshot_file_name_format.format(format='html') + if not slaveoutput: + if not os.path.exists(screenshot_dir): + os.makedirs(screenshot_dir) + else: + screenshot_dir = session_tmpdir.ensure('screenshots', dir=True).strpath + screenshot_png_path = os.path.join(screenshot_dir, screenshot_file_name) + screenshot_html_path = os.path.join(screenshot_dir, screenshot_html_file_name) + LOGGER.info('Saving screenshot to %s', screenshot_dir) + try: + splinter_screenshot_getter_html(browser_instance, screenshot_html_path) + splinter_screenshot_getter_png(browser_instance, screenshot_png_path) + if request.node.splinter_failure.longrepr: + reprtraceback = request.node.splinter_failure.longrepr.reprtraceback + reprtraceback.extraline = _screenshot_extraline(screenshot_png_path, screenshot_html_path) + if slaveoutput is not None: + with codecs.open(screenshot_html_path, encoding=splinter_screenshot_encoding) as html_fd: + with open(screenshot_png_path) as fd: + slaveoutput.setdefault('screenshots', []).append({ + 'class_name': classname, + 'files': [ + { + 'file_name': screenshot_file_name, + 'content': fd.read(), + }, + { + 'file_name': screenshot_html_file_name, + 'content': html_fd.read(), + 'encoding': splinter_screenshot_encoding + }] + }) + except Exception as e: # NOQA + request.config.warn('SPL504', "Could not save screenshot: {0}".format(e)) + + +@pytest.yield_fixture(autouse=True) +def _browser_screenshot_session( + request, + splinter_session_scoped_browser, + splinter_screenshot_dir, + splinter_make_screenshot_on_failure, + splinter_screenshot_getter_html, + splinter_screenshot_getter_png +): + """Make browser screenshot on test failure.""" + yield + + # Screenshot for function scoped browsers is handled in browser_instance_getter + if not splinter_session_scoped_browser: + return + + fixture_values = ( + # pytest 3 + getattr(request, '_fixture_values', {}) or + # pytest 2 + getattr(request, '_funcargs', {}) + ) + + for name, value in fixture_values.items(): + if hasattr(value, '__splinter_browser__'): + _take_screenshot( + request=request, + fixture_name=name, + browser_instance=value, + splinter_make_screenshot_on_failure=splinter_make_screenshot_on_failure, + splinter_screenshot_dir=splinter_screenshot_dir, + splinter_screenshot_getter_html=splinter_screenshot_getter_html, + splinter_screenshot_getter_png=splinter_screenshot_getter_png, + ) + + @pytest.fixture(scope='session') def browser_instance_getter( browser_patches, @@ -389,57 +484,6 @@ def get_browser(splinter_webdriver, retry_count=3): else: raise - def take_screenshot(request, parent, browser_instance): - name = parent.__name__ - - if splinter_make_screenshot_on_failure and getattr(request.node, 'splinter_failure', False): - slaveoutput = getattr(request.config, 'slaveoutput', None) - try: - names = junitxml.mangle_testnames(request.node.nodeid.split("::")) - except AttributeError: - # pytest>=2.9.0 - names = junitxml.mangle_test_address(request.node.nodeid) - - classname = '.'.join(names[:-1]) - screenshot_dir = os.path.join(splinter_screenshot_dir, classname) - screenshot_file_name_format = '{0}.{{format}}'.format( - '{0}-{1}'.format(names[-1][:128 - len(name) - 5], name).replace(os.path.sep, '-') - ) - screenshot_file_name = screenshot_file_name_format.format(format='png') - screenshot_html_file_name = screenshot_file_name_format.format(format='html') - if not slaveoutput: - if not os.path.exists(screenshot_dir): - os.makedirs(screenshot_dir) - else: - screenshot_dir = session_tmpdir.ensure('screenshots', dir=True).strpath - screenshot_png_path = os.path.join(screenshot_dir, screenshot_file_name) - screenshot_html_path = os.path.join(screenshot_dir, screenshot_html_file_name) - LOGGER.info('Saving screenshot to %s', screenshot_dir) - try: - splinter_screenshot_getter_html(browser_instance, screenshot_html_path) - splinter_screenshot_getter_png(browser_instance, screenshot_png_path) - if request.node.splinter_failure.longrepr: - reprtraceback = request.node.splinter_failure.longrepr.reprtraceback - reprtraceback.extraline = _screenshot_extraline(screenshot_png_path, screenshot_html_path) - if slaveoutput is not None: - with codecs.open(screenshot_html_path, encoding=splinter_screenshot_encoding) as html_fd: - with open(screenshot_png_path) as fd: - slaveoutput.setdefault('screenshots', []).append({ - 'class_name': classname, - 'files': [ - { - 'file_name': screenshot_file_name, - 'content': fd.read(), - }, - { - 'file_name': screenshot_html_file_name, - 'content': html_fd.read(), - 'encoding': splinter_screenshot_encoding - }] - }) - except Exception as e: # NOQA - request.config.warn('SPL504', "Could not save screenshot: {0}".format(e)) - def prepare_browser(request, parent): splinter_webdriver = request.getfuncargvalue('splinter_webdriver') splinter_session_scoped_browser = request.getfuncargvalue('splinter_session_scoped_browser') @@ -452,12 +496,19 @@ def prepare_browser(request, parent): request.addfinalizer(browser.quit) elif not browser: browser = browser_pool[browser_key] = get_browser(splinter_webdriver) - request.addfinalizer(functools.partial( - take_screenshot, - request=request, - parent=parent, - browser_instance=browser, - )) + + if request.scope == 'function': + request.addfinalizer(functools.partial( + _take_screenshot, + request=request, + fixture_name=parent.__name__, + browser_instance=browser, + splinter_make_screenshot_on_failure=splinter_make_screenshot_on_failure, + splinter_screenshot_dir=splinter_screenshot_dir, + splinter_screenshot_getter_html=splinter_screenshot_getter_html, + splinter_screenshot_getter_png=splinter_screenshot_getter_png, + + )) try: if splinter_webdriver not in browser.driver_name.lower(): raise IOError('webdriver does not match') From f8451fe8ba1168f373d4c2ae0dfc559c221b39dd Mon Sep 17 00:00:00 2001 From: Andreas Pelme Date: Wed, 2 Nov 2016 15:12:26 +0100 Subject: [PATCH 7/8] Review fixes --- pytest_splinter/plugin.py | 128 ++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 60 deletions(-) diff --git a/pytest_splinter/plugin.py b/pytest_splinter/plugin.py index f1014bf..0425361 100644 --- a/pytest_splinter/plugin.py +++ b/pytest_splinter/plugin.py @@ -340,59 +340,61 @@ def _take_screenshot( request, browser_instance, fixture_name, - splinter_make_screenshot_on_failure, splinter_screenshot_dir, splinter_screenshot_getter_html, splinter_screenshot_getter_png ): + """Capture a screenshot as .png and .html. - if splinter_make_screenshot_on_failure and request.node.splinter_failure: - slaveoutput = getattr(request.config, 'slaveoutput', None) - try: - names = junitxml.mangle_testnames(request.node.nodeid.split("::")) - except AttributeError: - # pytest>=2.9.0 - names = junitxml.mangle_test_address(request.node.nodeid) - - classname = '.'.join(names[:-1]) - screenshot_dir = os.path.join(splinter_screenshot_dir, classname) - screenshot_file_name_format = '{0}.{{format}}'.format( - '{0}-{1}'.format(names[-1][:128 - len(fixture_name) - 5], fixture_name).replace(os.path.sep, '-') - ) - screenshot_file_name = screenshot_file_name_format.format(format='png') - screenshot_html_file_name = screenshot_file_name_format.format(format='html') - if not slaveoutput: - if not os.path.exists(screenshot_dir): - os.makedirs(screenshot_dir) - else: - screenshot_dir = session_tmpdir.ensure('screenshots', dir=True).strpath - screenshot_png_path = os.path.join(screenshot_dir, screenshot_file_name) - screenshot_html_path = os.path.join(screenshot_dir, screenshot_html_file_name) - LOGGER.info('Saving screenshot to %s', screenshot_dir) - try: - splinter_screenshot_getter_html(browser_instance, screenshot_html_path) - splinter_screenshot_getter_png(browser_instance, screenshot_png_path) - if request.node.splinter_failure.longrepr: - reprtraceback = request.node.splinter_failure.longrepr.reprtraceback - reprtraceback.extraline = _screenshot_extraline(screenshot_png_path, screenshot_html_path) - if slaveoutput is not None: - with codecs.open(screenshot_html_path, encoding=splinter_screenshot_encoding) as html_fd: - with open(screenshot_png_path) as fd: - slaveoutput.setdefault('screenshots', []).append({ - 'class_name': classname, - 'files': [ - { - 'file_name': screenshot_file_name, - 'content': fd.read(), - }, - { - 'file_name': screenshot_html_file_name, - 'content': html_fd.read(), - 'encoding': splinter_screenshot_encoding - }] - }) - except Exception as e: # NOQA - request.config.warn('SPL504', "Could not save screenshot: {0}".format(e)) + Invoked from session and function browser fixtures. + """ + + slaveoutput = getattr(request.config, 'slaveoutput', None) + try: + names = junitxml.mangle_testnames(request.node.nodeid.split("::")) + except AttributeError: + # pytest>=2.9.0 + names = junitxml.mangle_test_address(request.node.nodeid) + + classname = '.'.join(names[:-1]) + screenshot_dir = os.path.join(splinter_screenshot_dir, classname) + screenshot_file_name_format = '{0}.{{format}}'.format( + '{0}-{1}'.format(names[-1][:128 - len(fixture_name) - 5], fixture_name).replace(os.path.sep, '-') + ) + screenshot_file_name = screenshot_file_name_format.format(format='png') + screenshot_html_file_name = screenshot_file_name_format.format(format='html') + if not slaveoutput: + if not os.path.exists(screenshot_dir): + os.makedirs(screenshot_dir) + else: + screenshot_dir = session_tmpdir.ensure('screenshots', dir=True).strpath + screenshot_png_path = os.path.join(screenshot_dir, screenshot_file_name) + screenshot_html_path = os.path.join(screenshot_dir, screenshot_html_file_name) + LOGGER.info('Saving screenshot to %s', screenshot_dir) + try: + splinter_screenshot_getter_html(browser_instance, screenshot_html_path) + splinter_screenshot_getter_png(browser_instance, screenshot_png_path) + if request.node.splinter_failure.longrepr: + reprtraceback = request.node.splinter_failure.longrepr.reprtraceback + reprtraceback.extraline = _screenshot_extraline(screenshot_png_path, screenshot_html_path) + if slaveoutput is not None: + with codecs.open(screenshot_html_path, encoding=splinter_screenshot_encoding) as html_fd: + with open(screenshot_png_path) as fd: + slaveoutput.setdefault('screenshots', []).append({ + 'class_name': classname, + 'files': [ + { + 'file_name': screenshot_file_name, + 'content': fd.read(), + }, + { + 'file_name': screenshot_html_file_name, + 'content': html_fd.read(), + 'encoding': splinter_screenshot_encoding + }] + }) + except Exception as e: # NOQA + request.config.warn('SPL504', "Could not save screenshot: {0}".format(e)) @pytest.yield_fixture(autouse=True) @@ -419,12 +421,17 @@ def _browser_screenshot_session( ) for name, value in fixture_values.items(): - if hasattr(value, '__splinter_browser__'): + should_take_screenshot = ( + hasattr(value, '__splinter_browser__') and + splinter_make_screenshot_on_failure and + request.node.splinter_failure + ) + + if should_take_screenshot: _take_screenshot( request=request, fixture_name=name, browser_instance=value, - splinter_make_screenshot_on_failure=splinter_make_screenshot_on_failure, splinter_screenshot_dir=splinter_screenshot_dir, splinter_screenshot_getter_html=splinter_screenshot_getter_html, splinter_screenshot_getter_png=splinter_screenshot_getter_png, @@ -498,17 +505,18 @@ def prepare_browser(request, parent): browser = browser_pool[browser_key] = get_browser(splinter_webdriver) if request.scope == 'function': - request.addfinalizer(functools.partial( - _take_screenshot, - request=request, - fixture_name=parent.__name__, - browser_instance=browser, - splinter_make_screenshot_on_failure=splinter_make_screenshot_on_failure, - splinter_screenshot_dir=splinter_screenshot_dir, - splinter_screenshot_getter_html=splinter_screenshot_getter_html, - splinter_screenshot_getter_png=splinter_screenshot_getter_png, + def _take_screenshot_on_failure(): + if splinter_make_screenshot_on_failure and request.node.splinter_failure: + _take_screenshot( + request=request, + fixture_name=parent.__name__, + browser_instance=browser, + splinter_screenshot_dir=splinter_screenshot_dir, + splinter_screenshot_getter_html=splinter_screenshot_getter_html, + splinter_screenshot_getter_png=splinter_screenshot_getter_png, + ) + request.addfinalizer(_take_screenshot_on_failure) - )) try: if splinter_webdriver not in browser.driver_name.lower(): raise IOError('webdriver does not match') From 554cc28c744b0413b9fb01ee2c0c679d39c15803 Mon Sep 17 00:00:00 2001 From: Andreas Pelme Date: Wed, 2 Nov 2016 15:36:45 +0100 Subject: [PATCH 8/8] Lint fix --- pytest_splinter/plugin.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pytest_splinter/plugin.py b/pytest_splinter/plugin.py index 0425361..feb66ab 100644 --- a/pytest_splinter/plugin.py +++ b/pytest_splinter/plugin.py @@ -348,7 +348,6 @@ def _take_screenshot( Invoked from session and function browser fixtures. """ - slaveoutput = getattr(request.config, 'slaveoutput', None) try: names = junitxml.mangle_testnames(request.node.nodeid.split("::"))