Support running feature tests against Firefox. Fixes #3270

This commit is contained in:
Akshay Joshi 2018-05-15 15:10:11 +01:00 committed by Dave Page
parent 8d9e9eab13
commit ccf58570b1
9 changed files with 104 additions and 15 deletions

1
.gitignore vendored
View File

@ -36,6 +36,7 @@ runtime/pgAdmin4_resource.rc
runtime/release/ runtime/release/
runtime/ui_BrowserWindow.h runtime/ui_BrowserWindow.h
web/config_local.py web/config_local.py
web/geckodriver.log
web/regression/test_config.json web/regression/test_config.json
node_modules/ node_modules/
web/pgAdmin/static/js/generated web/pgAdmin/static/js/generated

View File

@ -200,7 +200,7 @@ class CopySelectedQueryResultsFeatureTest(BaseFeatureTest):
ActionChains(self.page.driver).key_down( ActionChains(self.page.driver).key_down(
Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform() Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform()
self.assertEqual('"cool info"', pyperclip.paste()) self.assertIn('"cool info"', pyperclip.paste())
def after(self): def after(self):
self.page.close_query_tool() self.page.close_query_tool()

View File

@ -185,6 +185,8 @@ CREATE TABLE public.defaults_{0}
(By.XPATH, xpath)), CheckForViewDataTest.TIMEOUT_STRING (By.XPATH, xpath)), CheckForViewDataTest.TIMEOUT_STRING
) )
cell_el = self.page.find_by_xpath(xpath) cell_el = self.page.find_by_xpath(xpath)
self.page.driver.execute_script("arguments[0].scrollIntoView()",
cell_el)
ActionChains(self.driver).move_to_element(cell_el).double_click( ActionChains(self.driver).move_to_element(cell_el).double_click(
cell_el cell_el
).perform() ).perform()

View File

@ -8,6 +8,7 @@
########################################################################## ##########################################################################
import os import os
import time
from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By
@ -98,7 +99,18 @@ class CheckFileManagerFeatureTest(BaseFeatureTest):
self.page.find_by_id("file-input-path").send_keys( self.page.find_by_id("file-input-path").send_keys(
Keys.RETURN Keys.RETURN
) )
contents = self.page.find_by_id("contents").get_attribute('innerHTML')
if self.page.driver.capabilities['browserName'] == 'firefox':
table = self.page.wait_for_element_to_reload(
lambda driver:
driver.find_element_by_css_selector("table#contents")
)
else:
table = self.page.driver \
.find_element_by_css_selector("table#contents")
contents = table.get_attribute('innerHTML')
self.page.click_modal('Cancel') self.page.click_modal('Cancel')
self.page.wait_for_query_tool_loading_indicator_to_disappear() self.page.wait_for_query_tool_loading_indicator_to_disappear()
self._check_escaped_characters( self._check_escaped_characters(

View File

@ -127,6 +127,15 @@ Python Tests:
https://sites.google.com/a/chromium.org/chromedriver/downloads or a https://sites.google.com/a/chromium.org/chromedriver/downloads or a
package manager and make sure it is in the PATH package manager and make sure it is in the PATH
- For feature tests to run on Firefox, geckodriver need to be installed;
- Get geckodriver from https://github.com/mozilla/geckodriver/releases.
- Extract the binary and run chmod +x geckodriver.
- Copy geckodriver into /usr/local/bin or make sure path of the
geckodriver must be specified in the PATH.
- Set the "default_browser" parameter in test_config file or pass the command
line option --default_browser. Supported browsers are "Chrome" and
"Firefox".
- The test framework is modular and pluggable and dynamically locates tests - The test framework is modular and pluggable and dynamically locates tests
for modules which are discovered at runtime. All test cases are found for modules which are discovered at runtime. All test cases are found
and registered automatically by its module name in and registered automatically by its module name in

View File

@ -12,6 +12,7 @@ import signal
import random import random
import time import time
from selenium.common.exceptions import WebDriverException
class AppStarter: class AppStarter:
@ -41,10 +42,26 @@ class AppStarter:
env=env env=env
) )
self.driver.get( def launch_browser(retry_count):
"http://" + self.app_config.DEFAULT_SERVER + ":" + try:
random_server_port self.driver.get(
) "http://" + self.app_config.DEFAULT_SERVER + ":" +
random_server_port
)
except WebDriverException as e:
# In case of WebDriverException sleep for 1 second and retry
# again. Retry 10 times and if still app will not start then
# raise exception.
time.sleep(1)
if retry_count < 60:
retry_count = retry_count + 1
launch_browser(retry_count)
else:
raise Exception('Unable to start python server even after '
'retrying 60 times.')
launch_browser(0)
def stop_app(self): def stop_app(self):
""" This function stop the started app by killing process """ """ This function stop the started app by killing process """

View File

@ -60,6 +60,8 @@ class PgadminPage:
self.fill_input_by_field_name("port", server_config['port']) self.fill_input_by_field_name("port", server_config['port'])
self.fill_input_by_field_name("username", server_config['username']) self.fill_input_by_field_name("username", server_config['username'])
self.fill_input_by_field_name("password", server_config['db_password']) self.fill_input_by_field_name("password", server_config['db_password'])
# Required sleep to avoid "fe_sendauth" password error.
time.sleep(0.5)
self.find_by_xpath("//button[contains(.,'Save')]").click() self.find_by_xpath("//button[contains(.,'Save')]").click()
self.find_by_xpath( self.find_by_xpath(
@ -318,6 +320,14 @@ class PgadminPage:
self._wait_for("app to start", page_shows_app, self.app_start_timeout) self._wait_for("app to start", page_shows_app, self.app_start_timeout)
def wait_for_element_to_reload(self, element_selector):
WebDriverWait(self.driver, 20) \
.until(EC.staleness_of(element_selector(self.driver)))
WebDriverWait(self.driver, 20) \
.until_not(EC.staleness_of(element_selector(self.driver)))
return element_selector(self.driver)
def _wait_for(self, waiting_for_message, condition_met_function, def _wait_for(self, waiting_for_message, condition_met_function,
timeout=None): timeout=None):
if timeout is None: if timeout is None:

View File

@ -22,6 +22,7 @@ import json
from selenium import webdriver from selenium import webdriver
from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
if sys.version_info < (2, 7): if sys.version_info < (2, 7):
import unittest2 as unit_test import unittest2 as unit_test
@ -181,13 +182,40 @@ def get_test_modules(arguments):
exclude_pkgs += arguments['exclude'].split(',') exclude_pkgs += arguments['exclude'].split(',')
if 'feature_tests' not in exclude_pkgs: if 'feature_tests' not in exclude_pkgs:
options = Options() default_browser = 'chrome'
if test_setup.config_data:
if 'headless_chrome' in test_setup.config_data: # Check default browser provided through command line. If provided
if test_setup.config_data['headless_chrome']: # then use that browser as default browser else check for the setting
options.add_argument("--headless") # provided in test_config.json file.
options.add_argument("--window-size=1280x1024") if (
driver = webdriver.Chrome(chrome_options=options) 'default_browser' in arguments and
arguments['default_browser'] is not None
):
default_browser = arguments['default_browser'].lower()
elif (
test_setup.config_data and
"default_browser" in test_setup.config_data
):
default_browser = test_setup.config_data['default_browser'].lower()
if default_browser == 'firefox':
cap = DesiredCapabilities.FIREFOX
cap['requireWindowFocus'] = True
cap['enablePersistentHover'] = False
profile = webdriver.FirefoxProfile()
profile.set_preference("dom.disable_beforeunload", True)
driver = webdriver.Firefox(capabilities=cap,
firefox_profile=profile)
driver.implicitly_wait(1)
else:
options = Options()
if test_setup.config_data:
if 'headless_chrome' in test_setup.config_data:
if test_setup.config_data['headless_chrome']:
options.add_argument("--headless")
options.add_argument("--window-size=1280x1024")
driver = webdriver.Chrome(chrome_options=options)
app_starter = AppStarter(driver, config) app_starter = AppStarter(driver, config)
app_starter.start_app() app_starter.start_app()
@ -229,6 +257,10 @@ def add_arguments():
help='Skips execution of the test cases of particular package and ' help='Skips execution of the test cases of particular package and '
'sub-packages' 'sub-packages'
) )
parser.add_argument(
'--default_browser',
help='Executes the feature test in specific browser'
)
arg = parser.parse_args() arg = parser.parse_args()
return arg return arg
@ -341,7 +373,12 @@ if __name__ == '__main__':
sys.stderr = StreamToLogger(stderr_logger, logging.ERROR) sys.stderr = StreamToLogger(stderr_logger, logging.ERROR)
args = vars(add_arguments()) args = vars(add_arguments())
# Get test module list # Get test module list
test_module_list = get_test_modules(args) try:
test_module_list = get_test_modules(args)
except Exception as e:
print(str(e))
sys.exit(1)
# Login the test client # Login the test client
test_utils.login_tester_account(test_client) test_utils.login_tester_account(test_client)

View File

@ -1,5 +1,6 @@
{ {
"headless_chrome": false, "headless_chrome": false,
"default_browser": "Chrome",
"pgAdmin4_login_credentials": { "pgAdmin4_login_credentials": {
"new_password": "NEWPASSWORD", "new_password": "NEWPASSWORD",
"login_password": "PASSWORD", "login_password": "PASSWORD",