diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7f6de27..302106e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -71,6 +71,13 @@ jobs: go run -mod=vendor build/make.go --install --prefix=/tmp/gauge --verbose echo "::add-path::/tmp/gauge/bin" + - name: Install html report + run: | + git clone --depth=1 https://github.com/getgauge/html-report + cd html-report + go run build/make.go + go run build/make.go --install + - name: Install Python run: | pip install -r requirements.txt @@ -78,7 +85,7 @@ jobs: - name: Prep FTs run: | - git clone https://github.com/getgauge/gauge-tests + git clone --branch=fileBasedScreenshot https://github.com/getgauge/gauge-tests cd gauge-tests gauge install diff --git a/getgauge/executor.py b/getgauge/executor.py index 17b19d4..aeda180 100644 --- a/getgauge/executor.py +++ b/getgauge/executor.py @@ -35,7 +35,7 @@ def execute_method(params, step, response, is_continue_on_failure=_false): _add_exception(e, response, is_continue_on_failure(step.impl, e)) response.executionResult.executionTime = _current_time() - start response.executionResult.message.extend(MessagesStore.pending_messages()) - response.executionResult.screenshots.extend(ScreenshotsStore.pending_screenshots()) + response.executionResult.screenshotFiles.extend(ScreenshotsStore.pending_screenshots()) def _current_time(): return int(round(time.time() * 1000)) @@ -54,9 +54,8 @@ def _get_args(params, hook_or_step): def _add_exception(e, response, continue_on_failure): if os.getenv('screenshot_on_failure') == 'true': - screenshot = registry.screenshot_provider()() - response.executionResult.screenShot = screenshot - response.executionResult.failureScreenshot = screenshot + screenshot = ScreenshotsStore.capture_to_file() + response.executionResult.failureScreenshotFile = screenshot response.executionResult.failed = True message = e.__str__() if not message: @@ -67,4 +66,4 @@ def _add_exception(e, response, continue_on_failure): if continue_on_failure: response.executionResult.recoverableError = True response.executionResult.message.extend(MessagesStore.pending_messages()) - response.executionResult.screenshots.extend(ScreenshotsStore.pending_screenshots()) + response.executionResult.screenshotFiles.extend(ScreenshotsStore.pending_screenshots()) diff --git a/getgauge/python.py b/getgauge/python.py index a785283..6431a68 100644 --- a/getgauge/python.py +++ b/getgauge/python.py @@ -56,19 +56,23 @@ def after_step(obj=None): def screenshot(func): - _warn_screenshot_deprecation() - registry.set_screenshot_provider(func) + _warn_screenshot_deprecation('screenshot', 'custom_screenshot_writer') + registry.set_screenshot_provider(func, False) return func def custom_screen_grabber(func): - registry.set_screenshot_provider(func) + _warn_screenshot_deprecation('custom_screen_grabber', 'custom_screenshot_writer') + registry.set_screenshot_provider(func, False) return func +def custom_screenshot_writer(func): + registry.set_screenshot_provider(func, True) + return func -def _warn_screenshot_deprecation(): +def _warn_screenshot_deprecation(old_function, new_function): warnings.warn( - "'screenshot' is deprecated in favour of 'custom_screen_grabber'", + "'{0}' is deprecated in favour of '{1}'".format(old_function, new_function), DeprecationWarning, stacklevel=3) warnings.simplefilter('default', DeprecationWarning) diff --git a/getgauge/registry.py b/getgauge/registry.py index a15d331..56a8e9b 100644 --- a/getgauge/registry.py +++ b/getgauge/registry.py @@ -2,7 +2,7 @@ import os import re import sys -import tempfile +from uuid import uuid1 from subprocess import call from getgauge import logger @@ -107,6 +107,7 @@ class Registry(object): def __init__(self): self.__screenshot_provider, self.__steps_map, self.__continue_on_failures = _take_screenshot, {}, {} + self.is_screenshot_writer = True for hook in Registry.hooks: self.__def_hook(hook) @@ -150,8 +151,9 @@ def get_info_for(self, step_text): def get_infos_for(self, step_text): return self.__steps_map.get(step_text) - def set_screenshot_provider(self, func): + def set_screenshot_provider(self, func, is_writer): self.__screenshot_provider = func + self.is_screenshot_writer = is_writer def screenshot_provider(self): return self.__screenshot_provider @@ -226,13 +228,10 @@ def _get_step_value(step_text): def _take_screenshot(): - temp_file = os.path.join(tempfile.gettempdir(), 'screenshot.png') + temp_file = _uniqe_screenshot_file() try: call(['gauge_screenshot', temp_file]) - _file = open(temp_file, 'r+b') - data = _file.read() - _file.close() - return data + return os.path.basename(temp_file) except Exception as err: logger.error( "\nFailed to take screenshot using gauge_screenshot.\n{0}".format(err)) @@ -256,8 +255,31 @@ def pending_screenshots(): @staticmethod def capture(): - ScreenshotsStore.__screenshots.append(registry.screenshot_provider()()) + screenshot = ScreenshotsStore.capture_to_file() + ScreenshotsStore.__screenshots.append(screenshot) + + @staticmethod + def capture_to_file(): + if not registry.is_screenshot_writer: + screenshot_file = _uniqe_screenshot_file() + content = registry.screenshot_provider()() + file = open(screenshot_file, "wb") + file.write(content) + file.close() + return os.path.basename(screenshot_file) + screenshot_file = registry.screenshot_provider()() + if(not os.path.isabs(screenshot_file)): + screenshot_file = os.path.join(_screenshots_dir(), screenshot_file) + if(not os.path.exists(screenshot_file)): + logger.warning("Screenshot file {0} does not exists.".format(screenshot_file)) + return os.path.basename(screenshot_file) @staticmethod def clear(): ScreenshotsStore.__screenshots = [] + +def _uniqe_screenshot_file(): + return os.path.join(_screenshots_dir(), "screenshot-{0}.png".format(uuid1().int)) + +def _screenshots_dir(): + return os.getenv('screenshots_dir') \ No newline at end of file diff --git a/tests/test_data/impl_stubs.py b/tests/test_data/impl_stubs.py index f747043..457c4cd 100644 --- a/tests/test_data/impl_stubs.py +++ b/tests/test_data/impl_stubs.py @@ -87,4 +87,4 @@ def after_suite2(): @custom_screen_grabber def take_screenshot(): - return "foo" + return bytearray("foo", "utf-8") diff --git a/tests/test_python.py b/tests/test_python.py index 00b58eb..c31e0fe 100644 --- a/tests/test_python.py +++ b/tests/test_python.py @@ -6,6 +6,9 @@ DataStoreContainer, data_store, Table, Specification, Scenario, Step, ExecutionContext, create_execution_context_from) +from uuid import uuid1 +import os +import tempfile try: from collections.abc import MutableMapping except ImportError: @@ -508,11 +511,17 @@ def test_screenshot_decorator(self): class ScreenshotsTests(TestCase): + def setUp(self): + self.__old_screenshot_provider = registry.screenshot_provider() + self.__is_screenshot_writer = registry.is_screenshot_writer + os.environ["screenshots_dir"] = tempfile.mkdtemp() def test_pending_screenshots(self): ScreenshotsStore.capture() pending_screenshots = ScreenshotsStore.pending_screenshots() - self.assertEqual(['foo'], pending_screenshots) + self.assertEqual(1, len(pending_screenshots)) + self.assertTrue(os.path.exists(os.path.join( + os.getenv("screenshots_dir"), pending_screenshots[0]))) def test_clear(self): ScreenshotsStore.capture() @@ -523,12 +532,39 @@ def test_clear(self): def test_pending_screenshots_gives_only_those_screenshots_which_are_not_collected(self): ScreenshotsStore.capture() pending_screenshots = ScreenshotsStore.pending_screenshots() - self.assertEqual(['foo'], pending_screenshots) + self.assertEqual(1, len(pending_screenshots)) + screenshot_file = pending_screenshots[0] pending_screenshots = ScreenshotsStore.pending_screenshots() - self.assertEqual([], pending_screenshots) + self.assertEqual(0, len(pending_screenshots)) ScreenshotsStore.capture() pending_screenshots = ScreenshotsStore.pending_screenshots() - self.assertEqual(['foo'], pending_screenshots) + self.assertEqual(1, len(pending_screenshots)) + self.assertNotEqual(screenshot_file, pending_screenshots[0]) + + def test_capture_shoould_vefify_screenshot_file_for_file_based_custom_screenshot(self): + first_screenshot = os.path.join( + os.getenv("screenshots_dir"), "screenshot{0}.png".format(uuid1())) + second_screenshot = os.path.join( + os.getenv("screenshots_dir"), "screenshot{0}.png".format(uuid1())) + + def returns_abs_path(): + return first_screenshot + + def returns_base_ath(): + return os.path.basename(second_screenshot) + registry.set_screenshot_provider(returns_abs_path, True) + ScreenshotsStore.capture() + self.assertEqual([os.path.basename(first_screenshot)], + ScreenshotsStore.pending_screenshots()) + + registry.set_screenshot_provider(returns_base_ath, True) + ScreenshotsStore.capture() + self.assertEqual([os.path.basename(second_screenshot)], + ScreenshotsStore.pending_screenshots()) + + def tearDown(self): + registry.set_screenshot_provider( + self.__old_screenshot_provider, self.__is_screenshot_writer) if __name__ == '__main__':