From d756f2f6c637e52951356948ad0c188f66689be6 Mon Sep 17 00:00:00 2001 From: Joao Pedro De Almeida Pereira Date: Thu, 9 Mar 2017 15:34:51 +0000 Subject: [PATCH] Create screenshots when feature tests fail. --- .../connect_to_server_feature_test.py | 6 +- .../template_selection_feature_test.py | 6 +- .../settings/templates/settings/settings.js | 8 +- web/regression/.gitignore | 1 + .../feature_utils/base_feature_test.py | 73 ++++++++++++++++--- web/regression/feature_utils/pgadmin_page.py | 13 +++- web/regression/test_utils.py | 2 +- 7 files changed, 87 insertions(+), 22 deletions(-) diff --git a/web/pgadmin/feature_tests/connect_to_server_feature_test.py b/web/pgadmin/feature_tests/connect_to_server_feature_test.py index 9a7558d85..211385f85 100644 --- a/web/pgadmin/feature_tests/connect_to_server_feature_test.py +++ b/web/pgadmin/feature_tests/connect_to_server_feature_test.py @@ -19,9 +19,7 @@ class ConnectsToServerFeatureTest(BaseFeatureTest): Tests that a database connection can be created from the UI """ - def setUp(self): - super(ConnectsToServerFeatureTest, self).setUp() - + def before(self): connection = test_utils.get_db_connection(self.server['db'], self.server['username'], self.server['db_password'], @@ -38,7 +36,7 @@ class ConnectsToServerFeatureTest(BaseFeatureTest): self._connects_to_server() self._tables_node_expandable() - def tearDown(self): + def after(self): self.page.remove_server(self.server) connection = test_utils.get_db_connection(self.server['db'], diff --git a/web/pgadmin/feature_tests/template_selection_feature_test.py b/web/pgadmin/feature_tests/template_selection_feature_test.py index 4c37ebb48..7b7c039fc 100644 --- a/web/pgadmin/feature_tests/template_selection_feature_test.py +++ b/web/pgadmin/feature_tests/template_selection_feature_test.py @@ -5,9 +5,7 @@ from regression.feature_utils.base_feature_test import BaseFeatureTest class TemplateSelectionFeatureTest(BaseFeatureTest): - def setUp(self): - super(TemplateSelectionFeatureTest, self).setUp() - + def before(self): connection = test_utils.get_db_connection(self.server['db'], self.server['username'], self.server['db_password'], @@ -40,7 +38,7 @@ class TemplateSelectionFeatureTest(BaseFeatureTest): self.page.find_by_xpath("//*[contains(@class,'CodeMirror-lines') and contains(.,'LEAKPROOF')]") - def tearDown(self): + def after(self): self.page.find_by_xpath("//button[contains(.,'Cancel')]").click() self.page.remove_server(self.server) connection = test_utils.get_db_connection(self.server['db'], diff --git a/web/pgadmin/settings/templates/settings/settings.js b/web/pgadmin/settings/templates/settings/settings.js index 7bc9b3fee..716ca8850 100644 --- a/web/pgadmin/settings/templates/settings/settings.js +++ b/web/pgadmin/settings/templates/settings/settings.js @@ -23,12 +23,14 @@ define( // and reload the window show: function() { var obj = this; - alertify.confirm('{{ _('Reset layout') }}', - '{{ _('Are you sure you want to reset the current layout? This will cause the application to reload and any un-saved data will be lost.') }}', + alertify.confirm("{{ _('Reset layout') }}", + "{{ _('Are you sure you want to reset the current layout? This will cause the application to reload and any un-saved data will be lost.') }}", function() { + var reloadingIndicator = $('
'); + $('body').append(reloadingIndicator); // Delete the record from database as well, then only reload page $.ajax({ - url: '{{ url_for('settings.reset_layout') }}', + url: "{{ url_for('settings.reset_layout') }}", type: 'DELETE', async: false, success: function() { diff --git a/web/regression/.gitignore b/web/regression/.gitignore index 723fce7e4..ce544781c 100644 --- a/web/regression/.gitignore +++ b/web/regression/.gitignore @@ -3,3 +3,4 @@ regression.log test_greenplum_config.json test_advanced_config.json test_config.json +screenshots/ \ No newline at end of file diff --git a/web/regression/feature_utils/base_feature_test.py b/web/regression/feature_utils/base_feature_test.py index b88e0ebe6..34bf4f482 100644 --- a/web/regression/feature_utils/base_feature_test.py +++ b/web/regression/feature_utils/base_feature_test.py @@ -1,23 +1,78 @@ +import errno +import sys +import os + +from datetime import datetime + import config as app_config from pgadmin.utils.route import BaseTestGenerator from regression.feature_utils.pgadmin_page import PgadminPage class BaseFeatureTest(BaseTestGenerator): + CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) + def setUp(self): if app_config.SERVER_MODE: self.skipTest("Currently, config is set to start pgadmin in server mode. " "This test doesn't know username and password so doesn't work in server mode") self.page = PgadminPage(self.driver, app_config) - self.page.wait_for_app() - self.page.wait_for_spinner_to_disappear() - self.page.reset_layout() - self.page.wait_for_spinner_to_disappear() - - def failureException(self, *args, **kwargs): - self.page.driver.save_screenshot('/tmp/feature_test_failure.png') - return AssertionError(*args, **kwargs) + try: + self.page.wait_for_app() + self.page.wait_for_spinner_to_disappear() + self.page.reset_layout() + self.page.wait_for_spinner_to_disappear() + self.before() + except: + self._screenshot() + raise def runTest(self): - pass \ No newline at end of file + pass + + def before(self): + pass + + def after(self): + pass + + def tearDown(self): + python2_failures = hasattr(self, "_resultForDoCleanups") and self.current_test_failed() + + python3_failures = hasattr(self, '_outcome') and self.any_step_failed() + + if python2_failures or python3_failures: + self._screenshot() + + self.after() + + def any_step_failed(self): + for step in self._outcome.errors: + if step[1] is not None: + return True + return False + + def current_test_failed(self): + all_failures = self._resultForDoCleanups.errors + self._resultForDoCleanups.failures + for failure in all_failures: + if failure[0] == self: + return True + return False + + def _screenshot(self): + path = '{0}/../screenshots/{1}'.format(self.CURRENT_PATH, self.server["name"].replace(" ", "_")) + + try: + os.mkdir(path) + except OSError as e: + if e.errno == errno.EEXIST: + pass + else: + raise + + date = datetime.now().strftime("%Y.%m.%d_%H.%M.%S") + python_version = sys.version.split(" ")[0] + + self.page.driver.save_screenshot( + '{0}/{1}-{2}-Python-{3}.png'.format(path, self.__class__.__name__, date, python_version)) diff --git a/web/regression/feature_utils/pgadmin_page.py b/web/regression/feature_utils/pgadmin_page.py index 8622690ce..96c282109 100644 --- a/web/regression/feature_utils/pgadmin_page.py +++ b/web/regression/feature_utils/pgadmin_page.py @@ -22,9 +22,10 @@ class PgadminPage: self.click_element(self.find_by_partial_link_text("File")) self.find_by_partial_link_text("Reset Layout").click() self.click_modal_ok() + self.wait_for_reloading_indicator_to_disappear() def click_modal_ok(self): - time.sleep(0.1) + time.sleep(0.5) self.click_element(self.find_by_xpath("//button[contains(.,'OK')]")) def add_server(self, server_config): @@ -113,6 +114,16 @@ class PgadminPage: return self._wait_for("element to exist", element_if_it_exists) + def wait_for_reloading_indicator_to_disappear(self): + def reloading_indicator_has_disappeared(driver): + try: + driver.find_element_by_id("reloading-indicator") + return False + except NoSuchElementException: + return True + + self._wait_for("reloading indicator to disappear", reloading_indicator_has_disappeared) + def wait_for_spinner_to_disappear(self): def spinner_has_disappeared(driver): try: diff --git a/web/regression/test_utils.py b/web/regression/test_utils.py index ee8dcab13..f9cf93343 100644 --- a/web/regression/test_utils.py +++ b/web/regression/test_utils.py @@ -16,8 +16,8 @@ import sqlite3 from functools import partial import config -import test_setup import regression +from regression import test_setup SERVER_GROUP = test_setup.config_data['server_group'] file_name = os.path.realpath(__file__)