From 52bc460dffa6497a2074178d74aafeeeae0be292 Mon Sep 17 00:00:00 2001
From: "George Gelashvili, Sarah McAlear and Tira Odhner"
 <pair+ggelashvili+smcalear+aodhner@pivotal.io>
Date: Tue, 21 Feb 2017 11:25:36 -0500
Subject: [PATCH 1/2] Rename acceptance -> feature_tests and make tests less
 flaky by tearing down the database connection before running the test

---
 .../{acceptance => feature_tests}/__init__.py      |  0
 .../connect_to_server_feature_test.py              | 22 +++---------------
 .../template_selection_feature_test.py             | 24 ++++----------------
 web/pgadmin/utils/route.py                         |  2 +-
 web/regression/README                              |  6 ++---
 .../tests => regression/feature_utils}/__init__.py |  0
 .../{utils => feature_utils}/app_starter.py        |  0
 web/regression/feature_utils/base_feature_test.py  | 26 ++++++++++++++++++++++
 .../{utils => feature_utils}/pgadmin_page.py       |  6 ++++-
 web/regression/test_utils.py                       |  5 +++++
 web/regression/utils/__init__.py                   |  0
 11 files changed, 47 insertions(+), 44 deletions(-)
 rename web/pgadmin/{acceptance => feature_tests}/__init__.py (100%)
 rename web/pgadmin/{acceptance/tests => feature_tests}/connect_to_server_feature_test.py (78%)
 rename web/pgadmin/{acceptance/tests => feature_tests}/template_selection_feature_test.py (74%)
 rename web/{pgadmin/acceptance/tests => regression/feature_utils}/__init__.py (100%)
 rename web/regression/{utils => feature_utils}/app_starter.py (100%)
 create mode 100644 web/regression/feature_utils/base_feature_test.py
 rename web/regression/{utils => feature_utils}/pgadmin_page.py (95%)
 delete mode 100644 web/regression/utils/__init__.py

diff --git a/web/pgadmin/acceptance/__init__.py b/web/pgadmin/feature_tests/__init__.py
similarity index 100%
rename from web/pgadmin/acceptance/__init__.py
rename to web/pgadmin/feature_tests/__init__.py
diff --git a/web/pgadmin/acceptance/tests/connect_to_server_feature_test.py b/web/pgadmin/feature_tests/connect_to_server_feature_test.py
similarity index 78%
rename from web/pgadmin/acceptance/tests/connect_to_server_feature_test.py
rename to web/pgadmin/feature_tests/connect_to_server_feature_test.py
index c3bee4e6..2a7f638e 100644
--- a/web/pgadmin/acceptance/tests/connect_to_server_feature_test.py
+++ b/web/pgadmin/feature_tests/connect_to_server_feature_test.py
@@ -7,29 +7,20 @@
 #
 ##############################################################
 
-from selenium import webdriver
 from selenium.webdriver import ActionChains
 
 import config as app_config
-from pgadmin.utils.route import BaseTestGenerator
 from regression import test_utils
-from regression.utils.app_starter import AppStarter
-from regression.utils.pgadmin_page import PgadminPage
+from regression.feature_utils.base_feature_test import BaseFeatureTest
 
 
-class ConnectsToServerFeatureTest(BaseTestGenerator):
+class ConnectsToServerFeatureTest(BaseFeatureTest):
     """
     Tests that a database connection can be created from the UI
     """
 
     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")
-
-        driver = webdriver.Chrome()
-        self.app_starter = AppStarter(driver, app_config)
-        self.page = PgadminPage(driver, app_config)
+        super(ConnectsToServerFeatureTest, self).setUp()
 
         connection = test_utils.get_db_connection(self.server['db'],
                                                   self.server['username'],
@@ -40,9 +31,6 @@ class ConnectsToServerFeatureTest(BaseTestGenerator):
         test_utils.create_database(self.server, "acceptance_test_db")
         test_utils.create_table(self.server, "acceptance_test_db", "test_table")
 
-        self.app_starter.start_app()
-        self.page.wait_for_app()
-
     def runTest(self):
         self.assertEqual(app_config.APP_NAME, self.page.driver.title)
         self.page.wait_for_spinner_to_disappear()
@@ -61,10 +49,6 @@ class ConnectsToServerFeatureTest(BaseTestGenerator):
                                                   self.server['port'])
         test_utils.drop_database(connection, "acceptance_test_db")
 
-    def failureException(self, *args, **kwargs):
-        self.page.driver.save_screenshot('/tmp/pgadmin_connect_to_server_test_failure.png')
-        return AssertionError(*args, **kwargs)
-
     def _connects_to_server(self):
         self.page.find_by_xpath("//*[@class='aciTreeText' and .='Servers']").click()
         self.page.driver.find_element_by_link_text("Object").click()
diff --git a/web/pgadmin/acceptance/tests/template_selection_feature_test.py b/web/pgadmin/feature_tests/template_selection_feature_test.py
similarity index 74%
rename from web/pgadmin/acceptance/tests/template_selection_feature_test.py
rename to web/pgadmin/feature_tests/template_selection_feature_test.py
index b7405d56..858950f4 100644
--- a/web/pgadmin/acceptance/tests/template_selection_feature_test.py
+++ b/web/pgadmin/feature_tests/template_selection_feature_test.py
@@ -1,22 +1,13 @@
 from selenium import webdriver
 from selenium.webdriver import ActionChains
 
-import config as app_config
-from pgadmin.utils.route import BaseTestGenerator
 from regression import test_utils
-from regression.utils.app_starter import AppStarter
-from regression.utils.pgadmin_page import PgadminPage
+from regression.feature_utils.base_feature_test import BaseFeatureTest
 
 
-class TemplateSelectionFeatureTest(BaseTestGenerator):
+class TemplateSelectionFeatureTest(BaseFeatureTest):
     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")
-
-        driver = webdriver.Chrome()
-        self.app_starter = AppStarter(driver, app_config)
-        self.page = PgadminPage(driver, app_config)
+        super(TemplateSelectionFeatureTest, self).setUp()
 
         connection = test_utils.get_db_connection(self.server['db'],
                                                   self.server['username'],
@@ -27,9 +18,6 @@ class TemplateSelectionFeatureTest(BaseTestGenerator):
 
         test_utils.create_database(self.server, "acceptance_test_db")
 
-        self.app_starter.start_app()
-        self.page.wait_for_app()
-
         self.page.add_server(self.server)
 
     def runTest(self):
@@ -71,8 +59,4 @@ $BODY$
                                                   self.server['db_password'],
                                                   self.server['host'],
                                                   self.server['port'])
-        test_utils.drop_database(connection, "acceptance_test_db")
-
-    def failureException(self, *args, **kwargs):
-        self.page.driver.save_screenshot('/tmp/pgadmin_sql_template_selection_failure.png')
-        return AssertionError(*args, **kwargs)
+        test_utils.drop_database(connection, "acceptance_test_db")
\ No newline at end of file
diff --git a/web/pgadmin/utils/route.py b/web/pgadmin/utils/route.py
index 996892a6..2dea25d9 100644
--- a/web/pgadmin/utils/route.py
+++ b/web/pgadmin/utils/route.py
@@ -48,7 +48,7 @@ class TestsGeneratorRegistry(ABCMeta):
         # Register this type of module, based on the module name
         # Avoid registering the BaseDriver itself
 
-        if name != 'BaseTestGenerator':
+        if name != 'BaseTestGenerator' and name != 'BaseFeatureTest':
             TestsGeneratorRegistry.registry[d['__module__']] = cls
 
         ABCMeta.__init__(cls, name, bases, d)
diff --git a/web/regression/README b/web/regression/README
index 7101eb75..d16111b6 100644
--- a/web/regression/README
+++ b/web/regression/README
@@ -103,7 +103,7 @@ Test Data Details
 Execution:
 -----------
 
-- For acceptance tests to run as part of the entire test suite, Chrome and chromedriver need to be installed:
+- For feature tests to run as part of the entire test suite, Chrome and chromedriver need to be installed:
   get chromedriver from https://sites.google.com/a/chromium.org/chromedriver/downloads or a package manager
   and make sure it is on the PATH
 
@@ -137,8 +137,8 @@ Execution:
 
 - Exclude a package and its subpackages when running tests:
 
-    Example: exclude acceptance tests but run all others:
-    run 'python runtests.py --exclude acceptance'
+    Example: exclude feature tests but run all others:
+    run 'python runtests.py --exclude feature_tests'
 
     Example: exclude multiple packages:
     run 'python runtests.py --exclude browser.server_groups.servers.databases,browser.server_groups.servers.tablespaces'
diff --git a/web/pgadmin/acceptance/tests/__init__.py b/web/regression/feature_utils/__init__.py
similarity index 100%
rename from web/pgadmin/acceptance/tests/__init__.py
rename to web/regression/feature_utils/__init__.py
diff --git a/web/regression/utils/app_starter.py b/web/regression/feature_utils/app_starter.py
similarity index 100%
rename from web/regression/utils/app_starter.py
rename to web/regression/feature_utils/app_starter.py
diff --git a/web/regression/feature_utils/base_feature_test.py b/web/regression/feature_utils/base_feature_test.py
new file mode 100644
index 00000000..62d3bb36
--- /dev/null
+++ b/web/regression/feature_utils/base_feature_test.py
@@ -0,0 +1,26 @@
+from selenium import webdriver
+
+import config as app_config
+from pgadmin.utils.route import BaseTestGenerator
+from regression.feature_utils.app_starter import AppStarter
+from regression.feature_utils.pgadmin_page import PgadminPage
+
+
+class BaseFeatureTest(BaseTestGenerator):
+    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")
+
+        driver = webdriver.Chrome()
+        self.app_starter = AppStarter(driver, app_config)
+        self.page = PgadminPage(driver, app_config)
+        self.app_starter.start_app()
+        self.page.wait_for_app()
+
+    def failureException(self, *args, **kwargs):
+        self.page.driver.save_screenshot('/tmp/feature_test_failure.png')
+        return AssertionError(*args, **kwargs)
+
+    def runTest(self):
+        pass
\ No newline at end of file
diff --git a/web/regression/utils/pgadmin_page.py b/web/regression/feature_utils/pgadmin_page.py
similarity index 95%
rename from web/regression/utils/pgadmin_page.py
rename to web/regression/feature_utils/pgadmin_page.py
index d6a5836c..8d2843f6 100644
--- a/web/regression/utils/pgadmin_page.py
+++ b/web/regression/feature_utils/pgadmin_page.py
@@ -1,4 +1,5 @@
 import time
+
 from selenium.common.exceptions import NoSuchElementException
 from selenium.webdriver import ActionChains
 from selenium.webdriver.common.keys import Keys
@@ -65,6 +66,9 @@ class PgadminPage:
             "//pre[contains(@class,'CodeMirror-line')]/../../../*[contains(@class,'CodeMirror-code')]").click()
         ActionChains(self.driver).send_keys(field_content).perform()
 
+    def click_tab(self, tab_name):
+        self.find_by_xpath("//*[contains(@class,'wcPanelTab') and contains(.,'" + tab_name + "')]").click()
+
     def wait_for_input_field_content(self, field_name, content):
         def input_field_has_content():
             element = self.driver.find_element_by_xpath(
@@ -117,4 +121,4 @@ class PgadminPage:
             time_waited += sleep_time
             time.sleep(sleep_time)
 
-        raise RuntimeError("timed out waiting for " + waiting_for_message)
+        raise AssertionError("timed out waiting for " + waiting_for_message)
diff --git a/web/regression/test_utils.py b/web/regression/test_utils.py
index b4445d7d..1c2d244d 100644
--- a/web/regression/test_utils.py
+++ b/web/regression/test_utils.py
@@ -157,6 +157,11 @@ def drop_database(connection, database_name):
     """This function used to drop the database"""
     if database_name not in ["postgres", "template1", "template0"]:
         pg_cursor = connection.cursor()
+
+        pg_cursor.execute(
+            "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity "
+            "WHERE pg_stat_activity.datname ='%s' and pid <> pg_backend_pid();" % database_name
+                          )
         pg_cursor.execute("SELECT * FROM pg_database db WHERE"
                           " db.datname='%s'" % database_name)
         if pg_cursor.fetchall():
diff --git a/web/regression/utils/__init__.py b/web/regression/utils/__init__.py
deleted file mode 100644
index e69de29b..00000000
-- 
2.11.0

