1""" 2pytest hooks for interactive test cases. 3""" 4import inspect 5import pytest 6 7 8def pytest_collection_modifyitems(items, config): 9 """Determine whether test should be skipped based on command-line options.""" 10 sanity = config.getoption('--sanity', False) 11 non_interactive = config.getoption('--non-interactive', False) 12 13 remaining = [] 14 deselected = [] 15 for item in items: 16 if _skip_item(item, sanity, non_interactive): 17 deselected.append(item) 18 else: 19 remaining.append(item) 20 if deselected: 21 items[:] = remaining 22 config.hook.pytest_deselected(items=deselected) 23 24 25def _skip_item(item, sanity, non_interactive): 26 requires_user_action = item.get_closest_marker('requires_user_action') 27 requires_user_validation = item.get_closest_marker('requires_user_validation') 28 only_interactive = item.get_closest_marker('only_interactive') 29 30 if ((requires_user_action is not None or only_interactive is not None) 31 and (sanity or non_interactive)): 32 return True 33 34 if ((requires_user_validation is not None) 35 and (non_interactive)): 36 return True 37 38 return False 39 40def pytest_runtest_setup(item): 41 # TODO: Remove after migrating tests 42 sanity = item.config.getoption('--sanity', False) 43 non_interactive = item.config.getoption('--non-interactive', False) 44 interactive = not sanity and not non_interactive 45 46 if interactive: 47 _show_test_header(item) 48 _try_set_class_attribute(item, 'interactive', interactive) 49 _try_set_class_attribute(item, 'allow_missing_screenshots', sanity) 50 51def _show_test_header(item): 52 print() 53 print('='*80) 54 print(item.name) 55 print(_get_doc(item)) 56 print('-'*80) 57 58def _try_set_class_attribute(item, name, value): 59 if hasattr(item.obj, 'im_class'): 60 if hasattr(item.obj.im_class, name): 61 setattr(item.obj.im_class, name, value) 62 63def _get_doc(item): 64 i = item 65 while i is not None: 66 if hasattr(i, 'obj') and hasattr(i.obj, '__doc__') and i.obj.__doc__ is not None: 67 return inspect.cleandoc(i.obj.__doc__) 68 i = i.parent 69 70def pytest_runtest_makereport(item, call): 71 if call.when == 'call' and call.excinfo is None: 72 _legacy_check_screenshots(item) 73 _commit_screenshots(item) 74 75def _legacy_check_screenshots(item): 76 # TODO: Remove after migrating all tests 77 if hasattr(item, 'obj') and hasattr(item.obj, '__self__'): 78 if hasattr(item.obj.__self__, 'check_screenshots'): 79 item.obj.__self__.check_screenshots() 80 81def _commit_screenshots(item): 82 if hasattr(item.session, 'pending_screenshots'): 83 for fixture in item.session.pending_screenshots: 84 fixture.commit_screenshots() 85 86