def _take_screenshot(name): logger.info("Taking a screenshot named {}".format(name)) ss, ss_error = take_screenshot() g_id = fauxfactory.gen_alpha(length=6) if ss: fire_art_test_hook(item, 'filedump', description="Screenshot {}".format(name), file_type="screenshot", mode="wb", contents_base64=True, contents=ss, display_glyph="camera", group_id="fix-screenshot-{}".format(g_id), slaveid=store.slaveid) if ss_error: fire_art_test_hook(item, 'filedump', description="Screenshot error {}".format(name), mode="w", contents_base64=False, contents=ss_error, display_type="danger", group_id="fix-screenshot-{}".format(g_id), slaveid=store.slaveid)
def _take_screenshot(name): logger.info("Taking a screenshot named {}".format(name)) ss, ss_error = take_screenshot() g_id = fauxfactory.gen_alpha(length=6) if ss: fire_art_test_hook( item, 'filedump', description="Screenshot {}".format(name), file_type="screenshot", mode="wb", contents_base64=True, contents=ss, display_glyph="camera", group_id="fix-screenshot-{}".format(g_id), slaveid=store.slaveid) if ss_error: fire_art_test_hook( item, 'filedump', description="Screenshot error {}".format(name), mode="w", contents_base64=False, contents=ss_error, display_type="danger", group_id="fix-screenshot-{}".format(g_id), slaveid=store.slaveid)
def pytest_exception_interact(node, call, report): from cfme.fixtures.pytest_store import store from six.moves.http_client import BadStatusLine from socket import error val = safe_string(call.excinfo.value) if isinstance(call.excinfo.value, (URLError, BadStatusLine, error)): logger.error("internal Exception:\n %s", str(call.excinfo)) from cfme.utils.browser import manager manager.start() # start will quit first and cycle wharf as well last_lines = "\n".join(report.longreprtext.split("\n")[-4:]) short_tb = '{}\n{}\n{}'.format( last_lines, call.excinfo.type.__name__, val.encode('ascii', 'xmlcharrefreplace') ) fire_art_test_hook( node, 'filedump', description="Traceback", contents=report.longreprtext, file_type="traceback", display_type="danger", display_glyph="align-justify", group_id="pytest-exception", slaveid=store.slaveid) fire_art_test_hook( node, 'filedump', description="Short traceback", contents=short_tb, file_type="short_tb", display_type="danger", display_glyph="align-justify", group_id="pytest-exception", slaveid=store.slaveid) exception_name = call.excinfo.type.__name__ exception_lineno = call.excinfo.traceback[-1].lineno exception_filename = str(call.excinfo.traceback[-1].path).replace( project_path.strpath + "/", '' ) exception_location = "{}:{}".format(exception_filename, exception_lineno) fire_art_test_hook( node, 'tb_info', exception=exception_name, file_line=exception_location, short_tb=short_tb, slave_id=store.slaveid ) # base64 encoded to go into a data uri, same for screenshots tb = report.longreprtext if not isinstance(tb, six.binary_type): tb = tb.encode('utf-8') full_tb = base64.b64encode(tb) # errors are when exceptions are thrown outside of the test call phase report.when = getattr(report, 'when', 'setup') is_error = report.when != 'call' template_data = { 'name': node.name, 'file': node.fspath, 'is_error': is_error, 'fail_stage': report.when, 'short_tb': short_tb, 'full_tb': full_tb, } # Before trying to take a screenshot, we used to check if one of the browser_fixtures was # in this node's fixturenames, but that was too limited and preventing the capture of # screenshots. If removing that conditional now makes this too broad, we should consider # an isinstance(val, WebDriverException) check in addition to the browser fixture check that # exists here in commit 825ef50fd84a060b58d7e4dc316303a8b61b35d2 screenshot = take_screenshot() template_data['screenshot'] = screenshot.png template_data['screenshot_error'] = screenshot.error if screenshot.png: fire_art_test_hook( node, 'filedump', description="Exception screenshot", file_type="screenshot", mode="wb", contents_base64=True, contents=template_data['screenshot'], display_glyph="camera", group_id="pytest-exception", slaveid=store.slaveid) if screenshot.error: fire_art_test_hook( node, 'filedump', description="Screenshot error", mode="w", contents_base64=False, contents=template_data['screenshot_error'], display_type="danger", group_id="pytest-exception", slaveid=store.slaveid) failed_test_tracking['tests'].append(template_data) if is_error: failed_test_tracking['total_errored'] += 1 else: failed_test_tracking['total_failed'] += 1
def pytest_pyfunc_call(pyfuncitem): """Inspects and consumes certain exceptions The guts of this function are explained above in the module documentation. Args: pyfuncitem: A pytest test item. """ # do whatever you want before the next hook executes if not enable_rbac: yield return # Login as the "new" user to run the test under if 'rbac_role' in pyfuncitem.fixturenames: user = pyfuncitem._request.getfuncargvalue('rbac_role') really_logout() logger.info("setting user to {}".format(user)) user_obj = current_appliance.collections.users.instantiate( username=conf.credentials[user]['username'], password=conf.credentials[user]['password']) # Actually perform the test. outcome is set to be a result object from the test with user_obj: outcome = yield screenshot, screenshot_error = take_screenshot() # Handle the Exception logger.error(pyfuncitem.location[0]) loc = "{}/{}".format(pyfuncitem.location[0], pyfuncitem.location[2]) # loc = loc[:min([loc.rfind('['), len(loc)])] logger.error(loc) # errors = [v for k, v in tests.items() if loc.startswith(k)] errors = pyfuncitem.function.meta.kwargs['from_docs']['rbac']['roles'] if errors: # errors = errors[0] user = pyfuncitem.funcargs['rbac_role'] if errors[user]: if not outcome.excinfo: logger.error("RBAC: Test should fail!") raise Exception("RBAC: You should fail!") else: if outcome.excinfo[1].__repr__().startswith(errors[user]): logger.info("RBAC: Test failed as expected") outcome.force_result(True) else: contents = "".join( traceback.format_list( traceback.extract_tb(outcome.excinfo[2]))) save_traceback_file(pyfuncitem, contents) save_screenshot(pyfuncitem, screenshot, screenshot_error) logger.error("RBAC: You blithering idiot, " "you failed with the wrong exception") raise Exception( "RBAC: You should fail with {}!".format( errors[user])) else: if not outcome.excinfo: logger.info("RBAC: Test passed as expected") else: logger.error("RBAC: Test should have passed!") contents = "".join( traceback.format_list( traceback.extract_tb(outcome.excinfo[2]))) save_traceback_file(pyfuncitem, contents) save_screenshot(pyfuncitem, screenshot, screenshot_error) raise Exception("RBAC: Test should have passed!")
def pytest_exception_interact(node, call, report): from fixtures.pytest_store import store from six.moves.http_client import BadStatusLine from socket import error val = safe_string(call.excinfo.value.message).decode('utf-8', 'ignore') if isinstance(call.excinfo.value, (URLError, BadStatusLine, error)): logger.error("internal Exception:\n %s", str(call.excinfo)) from cfme.utils.browser import manager manager.start() # start will quit first and cycle wharf as well last_lines = "\n".join(report.longreprtext.split("\n")[-4:]) short_tb = '{}\n{}\n{}'.format( last_lines, call.excinfo.type.__name__, val.encode('ascii', 'xmlcharrefreplace') ) fire_art_test_hook( node, 'filedump', description="Traceback", contents=report.longreprtext, file_type="traceback", display_type="danger", display_glyph="align-justify", group_id="pytest-exception", slaveid=store.slaveid) fire_art_test_hook( node, 'filedump', description="Short traceback", contents=short_tb, file_type="short_tb", display_type="danger", display_glyph="align-justify", group_id="pytest-exception", slaveid=store.slaveid) exception_name = call.excinfo.type.__name__ exception_lineno = call.excinfo.traceback[-1].lineno exception_filename = str(call.excinfo.traceback[-1].path).replace( project_path.strpath + "/", '' ) exception_location = "{}:{}".format(exception_filename, exception_lineno) fire_art_test_hook( node, 'tb_info', exception=exception_name, file_line=exception_location, short_tb=short_tb, slave_id=store.slaveid ) # base64 encoded to go into a data uri, same for screenshots full_tb = report.longreprtext.encode('base64').strip() # errors are when exceptions are thrown outside of the test call phase report.when = getattr(report, 'when', 'setup') is_error = report.when != 'call' template_data = { 'name': node.name, 'file': node.fspath, 'is_error': is_error, 'fail_stage': report.when, 'short_tb': short_tb, 'full_tb': full_tb, } # Before trying to take a screenshot, we used to check if one of the browser_fixtures was # in this node's fixturenames, but that was too limited and preventing the capture of # screenshots. If removing that conditional now makes this too broad, we should consider # an isinstance(val, WebDriverException) check in addition to the browser fixture check that # exists here in commit 825ef50fd84a060b58d7e4dc316303a8b61b35d2 screenshot = take_screenshot() template_data['screenshot'] = screenshot.png template_data['screenshot_error'] = screenshot.error if screenshot.png: fire_art_test_hook( node, 'filedump', description="Exception screenshot", file_type="screenshot", mode="wb", contents_base64=True, contents=template_data['screenshot'], display_glyph="camera", group_id="pytest-exception", slaveid=store.slaveid) if screenshot.error: fire_art_test_hook( node, 'filedump', description="Screenshot error", mode="w", contents_base64=False, contents=template_data['screenshot_error'], display_type="danger", group_id="pytest-exception", slaveid=store.slaveid) failed_test_tracking['tests'].append(template_data) if is_error: failed_test_tracking['total_errored'] += 1 else: failed_test_tracking['total_failed'] += 1
def pytest_pyfunc_call(pyfuncitem): """Inspects and consumes certain exceptions The guts of this function are explained above in the module documentation. Args: pyfuncitem: A pytest test item. """ # do whatever you want before the next hook executes if not enable_rbac: yield return # Login as the "new" user to run the test under if 'rbac_role' in pyfuncitem.fixturenames: user = pyfuncitem._request.getfuncargvalue('rbac_role') really_logout() logger.info("setting user to {}".format(user)) user_obj = current_appliance.collections.users.instantiate( username=conf.credentials[user]['username'], password=conf.credentials[user]['password'] ) # Actually perform the test. outcome is set to be a result object from the test with user_obj: outcome = yield screenshot, screenshot_error = take_screenshot() # Handle the Exception logger.error(pyfuncitem.location[0]) loc = "{}/{}".format(pyfuncitem.location[0], pyfuncitem.location[2]) # loc = loc[:min([loc.rfind('['), len(loc)])] logger.error(loc) # errors = [v for k, v in tests.items() if loc.startswith(k)] errors = pyfuncitem.function.meta.kwargs['from_docs']['rbac']['roles'] if errors: # errors = errors[0] user = pyfuncitem.funcargs['rbac_role'] if errors[user]: if not outcome.excinfo: logger.error("RBAC: Test should fail!") raise Exception("RBAC: You should fail!") else: if outcome.excinfo[1].__repr__().startswith(errors[user]): logger.info("RBAC: Test failed as expected") outcome.force_result(True) else: contents = "".join(traceback.format_list( traceback.extract_tb(outcome.excinfo[2]))) save_traceback_file(pyfuncitem, contents) save_screenshot(pyfuncitem, screenshot, screenshot_error) logger.error("RBAC: You blithering idiot, " "you failed with the wrong exception") raise Exception("RBAC: You should fail with {}!".format(errors[user])) else: if not outcome.excinfo: logger.info("RBAC: Test passed as expected") else: logger.error("RBAC: Test should have passed!") contents = "".join(traceback.format_list( traceback.extract_tb(outcome.excinfo[2]))) save_traceback_file(pyfuncitem, contents) save_screenshot(pyfuncitem, screenshot, screenshot_error) raise Exception("RBAC: Test should have passed!")