Here's an updated patch which polls to wait for the app to start instead of
sleeping for 10 seconds.

On Thu, Jan 19, 2017 at 5:07 PM, George Gelashvili <ggelashv...@pivotal.io>
wrote:

>
> Here is an updated patch which starts the server up when the test starts
> and uses the values from config.py for server name etc. It still requires
> installing chromedriver before running. Should we add something to the
> readme about that?
>
> On Tue, Jan 17, 2017 at 11:09 AM, Atira Odhner <aodh...@pivotal.io> wrote:
>
>> Thanks for your feedback, Dave!
>>
>> We can put the tests under the regression directory. I think that makes
>> sense.
>> I'm not picturing these tests being module specific, but we may want to
>> enable running it as a separate suite of tests.
>>
>> Thanks for the callout about the port and title. We'll make sure those
>> are pulled from config or that the pgAdmin server is spun up by the test
>> with specific values.
>>
>> I have a couple ideas about why the test might not have been running for
>> you. I think the patch we attached didn't spin up its own pgAdmin yet and
>> it definitely doesn't fill in username/password if your app is running that
>> way. That's part of the WIP-ness :-P
>>
>> -Tira
>>
>> Hi
>>
>> On Thu, Jan 12, 2017 at 10:41 PM, George Gelashvili
>> <ggelashvili(at)pivotal(dot)io> wrote:
>> > here's the patch we forgot to attach. Also, you can see work on our branch
>> > at:
>> > https://github.com/pivotalsoftware/pgadmin4/tree/pivotal/acceptance-tests
>> >
>> > On Thu, Jan 12, 2017 at 5:26 PM, George Gelashvili 
>> > <ggelashvili(at)pivotal(dot)io>
>> > wrote:
>> >>
>> >> Hi there,
>> >>
>> >> We are working on browser-automation-based acceptance tests that exercise
>> >> pgAdmin4 the way a user might.
>>
>> Nice!
>>
>> >> The first "connect to database" test works, but at the moment depends on
>> >> Chrome and chromedriver. We would appreciate feedback on any possible
>> >> license or code style issues at this point, as well as any thoughts on
>> >> adding this sort of test to the codebase.
>>
>> A few thoughts:
>>
>> - If these tests are to run as part of the regression suite, the
>> framework for them should live under that directory.
>>
>> - Are any of the tests likely to be module-specific? If so, they
>> should really be part of the relevant module as the regression tests
>> are. If they're more general/less tightly coupled, then I don't see a
>> problem with them residing where they are.
>>
>> - Please take care not to include changes to .gitgnore files that
>> aren't relevant to the rest of us.
>>
>> - The port number is hard-coded in the test.
>>
>> - You've hard-coded the string "pgAdmin 4". We've tried to keep that
>> title as a config option in config.py, so you should pull the string
>> from there rather than hard-coding it.
>>
>> - The connect test fails for me (Mac, Python 2.7). I have a suspicion
>> that this may be because when the test starts chromedriver, OS X
>> prompts the user about whether a listening port should be opened, but
>> the tests don't wait (though, I tested with 3 servers configured and
>> it failed with the same error on the second and third as well, long
>> after I clicked OK on the prompt):
>>
>> Traceback (most recent call last):
>>   File 
>> "/Users/dpage/git/pgadmin4/web/acceptance/test_connects_to_database.py",
>> line 32, in runTest
>>     self.assertEqual("pgAdmin 4", self.driver.title)
>> AssertionError: 'pgAdmin 4' != u'localhost'
>>
>> - Please keep tests in the pgadmin. namespace (pgadmin.acceptance.??).
>>
>> - It looks like running a single test won't work yet (because of
>> TestsGeneratorRegistry.load_generators('pgadmin.%s.tests' %
>> arguments['pkg']))
>>
>> Thanks!
>>
>> --
>> Dave Page
>> Blog: http://pgsnake.blogspot.com
>>
>> Twitter: @pgsnake
>>
>> EnterpriseDB UK: http://www.enterprisedb.com
>> The Enterprise PostgreSQL Company
>>
>>
>>
>
diff --git a/requirements_py2.txt b/requirements_py2.txt
index 51170a45..de167121 100644
--- a/requirements_py2.txt
+++ b/requirements_py2.txt
@@ -36,6 +36,7 @@ testscenarios==0.5.0
 testtools==2.0.0
 traceback2==1.4.0
 unittest2==1.1.0
+selenium==3.0.2
 Werkzeug==0.9.6
 WTForms==2.0.2
 sqlparse==0.1.19
diff --git a/requirements_py3.txt b/requirements_py3.txt
index f68db7a8..9565a6e4 100644
--- a/requirements_py3.txt
+++ b/requirements_py3.txt
@@ -35,6 +35,7 @@ testscenarios==0.5.0
 testtools==2.0.0
 traceback2==1.4.0
 unittest2==1.1.0
+selenium==3.0.2
 Werkzeug==0.9.6
 WTForms==2.0.2
 sqlparse==0.1.19
diff --git a/web/pgadmin/acceptance/__init__.py 
b/web/pgadmin/acceptance/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/web/pgadmin/acceptance/tests/__init__.py 
b/web/pgadmin/acceptance/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/web/pgadmin/acceptance/tests/test_connects_to_database.py 
b/web/pgadmin/acceptance/tests/test_connects_to_database.py
new file mode 100644
index 00000000..2c4f85c4
--- /dev/null
+++ b/web/pgadmin/acceptance/tests/test_connects_to_database.py
@@ -0,0 +1,123 @@
+#############################################################
+#
+# pgAdmin 4 - PostgreSQL Tools
+#
+# Copyright (C) 2013 - 2017, The pgAdmin Development Team
+# This software is released under the PostgreSQL Licence
+#
+##############################################################
+
+import time
+
+from selenium import webdriver
+from selenium.common.exceptions import NoSuchElementException
+from selenium.webdriver import ActionChains
+
+from pgadmin.utils.route import BaseTestGenerator
+
+import subprocess
+import os
+import signal
+import config
+
+
+class ConnectsToDatabase(BaseTestGenerator):
+    """
+    Tests that a database connection can be created from the UI
+    """
+
+    def setUp(self):
+        if (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.pgadmin_process = subprocess.Popen(["python", "pgAdmin4.py"], 
shell=False, preexec_fn=os.setsid, stderr=open(os.devnull, 'w'))
+
+        self.driver = webdriver.Chrome()
+        self.server_config = self.server
+
+        print("opening browser")
+        self.driver.get("http://"; + config.DEFAULT_SERVER + ":" + 
str(config.DEFAULT_SERVER_PORT))
+        self._wait_for_app()
+
+    def runTest(self):
+        self.assertEqual(config.APP_NAME, self.driver.title)
+        self._wait_for_spinner_to_disappear()
+
+        self._find_by_xpath("//*[@class='aciTreeText' and 
.='Servers']").click()
+        self.driver.find_element_by_link_text("Object").click()
+        ActionChains(self.driver) \
+            .move_to_element(self.driver.find_element_by_link_text("Create")) \
+            .perform()
+        self._find_by_partial_link_text("Server...").click()
+
+        self._fill_input_by_xpath("name", self.server_config['name'])
+        self._find_by_partial_link_text("Connection").click()
+        self._fill_input_by_xpath("host", self.server_config['host'])
+        self._fill_input_by_xpath("port", self.server_config['port'])
+        self._fill_input_by_xpath("username", self.server_config['username'])
+        self._fill_input_by_xpath("password", 
self.server_config['db_password'])
+        self._find_by_xpath("//button[contains(.,'Save')]").click()
+
+        self._find_by_xpath("//*[@id='tree']//*[.='" + 
self.server_config['name'] + "']")
+
+    def tearDown(self):
+        self.driver.close()
+        os.killpg(os.getpgid(self.pgadmin_process.pid), signal.SIGTERM)
+
+    def failureException(self, *args, **kwargs):
+        self.driver.save_screenshot('/tmp/pgadmin_test_screenshot.png')
+        return AssertionError(*args, **kwargs)
+
+    def _find_by_xpath(self, xpath):
+        return self._wait_for_element(lambda: 
self.driver.find_element_by_xpath(xpath))
+
+    def _find_by_partial_link_text(self, link_text):
+        return self._wait_for_element(lambda: 
self.driver.find_element_by_partial_link_text(link_text))
+
+    def _fill_input_by_xpath(self, field_name, field_content):
+        self._find_by_xpath("//input[@name='" + field_name + "']").clear()
+        self._find_by_xpath("//input[@name='" + field_name + "']").send_keys(
+            field_content)
+
+    def _wait_for_element(self, find_method_with_args):
+        def element_if_it_exists():
+            try:
+                element = find_method_with_args()
+                if element.is_displayed() & element.is_enabled():
+                    return element
+            except NoSuchElementException:
+                return False
+
+        return self.__wait_for("element to exist", element_if_it_exists)
+
+    def _wait_for_spinner_to_disappear(self):
+        def spinner_has_disappeared():
+            try:
+                self.driver.find_element_by_id("pg-spinner")
+                return False
+            except NoSuchElementException:
+                return True
+
+        self.__wait_for("spinner to disappear", spinner_has_disappeared)
+
+    def _wait_for_app(self):
+        def page_shows_app():
+            self.driver.refresh()
+            return self.driver.title == config.APP_NAME
+
+        self.__wait_for("app to start", page_shows_app)
+
+    def __wait_for(self, waiting_for_message, condition_met_function):
+        timeout = 5
+        time_waited = 0
+        sleep_time = 0.01
+
+        while time_waited < timeout:
+            result = condition_met_function()
+            if(result):
+                return result
+            time_waited += sleep_time
+            time.sleep(sleep_time)
+
+        self.fail("Timed out waiting for " + waiting_for_message)
diff --git a/web/pgadmin/utils/route.py b/web/pgadmin/utils/route.py
index f18d2c18..fed26a0f 100644
--- a/web/pgadmin/utils/route.py
+++ b/web/pgadmin/utils/route.py
@@ -54,20 +54,25 @@ class TestsGeneratorRegistry(ABCMeta):
         ABCMeta.__init__(cls, name, bases, d)
 
     @classmethod
-    def load_generators(cls, pkg):
+    def load_generators(cls, *pkgs):
 
         cls.registry = dict()
 
+        all_modules = []
+
+        for pkg in pkgs:
+            all_modules += find_modules(pkg, False, True)
+
+
         # Check for SERVER mode
-        if config.SERVER_MODE:
-            for module_name in find_modules(pkg, False, True):
+        for module_name in all_modules:
+            if config.SERVER_MODE:
                 try:
                     if "tests." in str(module_name):
                         import_module(module_name)
                 except ImportError:
                     traceback.print_exc(file=sys.stderr)
-        else:
-            for module_name in find_modules(pkg, False, True):
+            else:
                 try:
                     # Exclude the test cases in browser node if SERVER_MODE
                     # is False
diff --git a/web/regression/.gitignore b/web/regression/.gitignore
index 0581810b..723fce7e 100644
--- a/web/regression/.gitignore
+++ b/web/regression/.gitignore
@@ -1,4 +1,5 @@
 parent_id.pkl
 regression.log
+test_greenplum_config.json
 test_advanced_config.json
 test_config.json
-- 
Sent via pgadmin-hackers mailing list (pgadmin-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers

Reply via email to