From 6fa6939f52c9c0ccea90e1ca6c1b7d8073d2f5d0 Mon Sep 17 00:00:00 2001 From: Aditya Toshniwal Date: Wed, 17 Oct 2018 11:50:22 +0100 Subject: [PATCH] Additional feature test fixes: 1) Changes required for working with Bootstrap 4. 2) Change to fix the timeout exception when waiting for element (tested multiple times on multiple server, did not occur to me thereafter) 3) Removed reset layout after each test case. Instead, delete the layout entry from sqlite db file and do a plain refresh. This will save some time and will also remove dependency on reset layout menu. 4) Disables tree state saving when feature test run starts. Feature tests got confused with auto expanding tree. --- .../feature_tests/browser_tool_bar_test.py | 1 + .../feature_tests/file_manager_test.py | 4 +- .../feature_tests/keyboard_shortcut_test.py | 4 +- .../pg_datatype_validation_test.py | 4 +- .../pg_utilities_backup_restore_test.py | 13 ++---- .../feature_utils/base_feature_test.py | 4 +- web/regression/feature_utils/pgadmin_page.py | 32 ++++++++----- .../python_test_utils/test_utils.py | 45 +++++++++++++++++++ web/regression/runtests.py | 3 ++ 9 files changed, 85 insertions(+), 25 deletions(-) diff --git a/web/pgadmin/feature_tests/browser_tool_bar_test.py b/web/pgadmin/feature_tests/browser_tool_bar_test.py index ca89f9d54..e53c73907 100644 --- a/web/pgadmin/feature_tests/browser_tool_bar_test.py +++ b/web/pgadmin/feature_tests/browser_tool_bar_test.py @@ -80,6 +80,7 @@ class BrowserToolBarFeatureTest(BaseFeatureTest): self.page.find_by_xpath("//*[contains(@class,'wcTabIcon fa fa-bolt')]") def test_view_data_tool_button(self): + self.page.select_tree_item(self.test_db) self.page.toggle_open_tree_item('Schemas') self.page.toggle_open_tree_item('public') self.page.toggle_open_tree_item('Tables') diff --git a/web/pgadmin/feature_tests/file_manager_test.py b/web/pgadmin/feature_tests/file_manager_test.py index 0c6e03047..898988136 100644 --- a/web/pgadmin/feature_tests/file_manager_test.py +++ b/web/pgadmin/feature_tests/file_manager_test.py @@ -41,7 +41,7 @@ class CheckFileManagerFeatureTest(BaseFeatureTest): os.remove(self.XSS_FILE) def after(self): - self.page.close_query_tool('sql', False) + self.page.close_query_tool('.sql', False) self.page.remove_server(self.server) def runTest(self): @@ -179,3 +179,5 @@ class CheckFileManagerFeatureTest(BaseFeatureTest): if not success: raise Exception("Unable to sort in descending order while clicked " "on 'Name' column") + + self.page.click_modal('Cancel') diff --git a/web/pgadmin/feature_tests/keyboard_shortcut_test.py b/web/pgadmin/feature_tests/keyboard_shortcut_test.py index bbae1940b..9ad42f677 100644 --- a/web/pgadmin/feature_tests/keyboard_shortcut_test.py +++ b/web/pgadmin/feature_tests/keyboard_shortcut_test.py @@ -74,11 +74,11 @@ class KeyboardShortcutFeatureTest(BaseFeatureTest): EC.presence_of_element_located( (By.XPATH, "//li[contains(@id, " + s + - ") and contains(@class, 'open')]") + ") and contains(@class, 'show')]") ) ) - is_open = 'open' in self.page.find_by_id(s).get_attribute('class') + is_open = 'show' in self.page.find_by_id(s).get_attribute('class') assert is_open is True, "Keyboard shortcut change is unsuccessful." diff --git a/web/pgadmin/feature_tests/pg_datatype_validation_test.py b/web/pgadmin/feature_tests/pg_datatype_validation_test.py index 47f716067..4f55a1453 100644 --- a/web/pgadmin/feature_tests/pg_datatype_validation_test.py +++ b/web/pgadmin/feature_tests/pg_datatype_validation_test.py @@ -29,6 +29,8 @@ try: test_data_configuration['datatype_minimum_version'] except Exception as e: print(str(e)) + assert False, \ + "datatype_test.json file load failed" class PGDataypeFeatureTest(BaseFeatureTest): @@ -88,7 +90,7 @@ class PGDataypeFeatureTest(BaseFeatureTest): ".ajs-dialog.pg-el-container .ajs-maximize").click() sql_editor = self.page.find_by_xpath( - "//*[contains(@class,'aciTreeLi') and contains(.,'SQL Editor')]") + "//*[contains(@class,'aciTreeLi') and contains(.,'Query Tool')]") sql_editor.find_element_by_xpath( "//*[contains(@class,'aciTreeText') and contains(.,'Options')]" diff --git a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py index 19b33e4c8..0e4b268dd 100644 --- a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py +++ b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py @@ -55,10 +55,10 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest): self.page.find_by_partial_link_text("Backup...").click() self.wait.until(EC.element_to_be_clickable( - (By.CSS_SELECTOR, ".browse_file_input"))) + (By.CSS_SELECTOR, ".file [name='file']"))) self.wait.until(EC.element_to_be_clickable( - (By.CSS_SELECTOR, ".browse_file_input"))).click() + (By.CSS_SELECTOR, ".file [name='file']"))).click() self.page.fill_input_by_field_name("file", "test_backup") @@ -98,15 +98,10 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest): self.page.find_by_partial_link_text("Restore...").click() self.wait.until(EC.element_to_be_clickable( - (By.CSS_SELECTOR, ".browse_file_input"))) - - self.page.find_by_xpath( - "//button[contains(@class,'fa-info') and " - "contains(@label, 'Restore')]" - ) + (By.CSS_SELECTOR, ".file [name='file']"))) self.wait.until(EC.element_to_be_clickable( - (By.CSS_SELECTOR, ".browse_file_input"))).click() + (By.CSS_SELECTOR, ".file [name='file']"))).click() self.page.fill_input_by_field_name("file", "test_backup") diff --git a/web/regression/feature_utils/base_feature_test.py b/web/regression/feature_utils/base_feature_test.py index 568fc2e9b..0fdd0b66c 100644 --- a/web/regression/feature_utils/base_feature_test.py +++ b/web/regression/feature_utils/base_feature_test.py @@ -18,6 +18,7 @@ from copy import deepcopy import config as app_config from pgadmin.utils.route import BaseTestGenerator from regression.feature_utils.pgadmin_page import PgadminPage +from regression.python_test_utils import test_utils class BaseFeatureTest(BaseTestGenerator): @@ -35,10 +36,11 @@ class BaseFeatureTest(BaseTestGenerator): self.page = PgadminPage(self.driver, app_config) try: + test_utils.reset_layout_db() self.page.driver.switch_to.default_content() self.page.wait_for_app() self.page.wait_for_spinner_to_disappear() - self.page.reset_layout() + self.page.refresh_page() self.page.wait_for_spinner_to_disappear() self.before() except Exception: diff --git a/web/regression/feature_utils/pgadmin_page.py b/web/regression/feature_utils/pgadmin_page.py index eea9b2772..d915e5697 100644 --- a/web/regression/feature_utils/pgadmin_page.py +++ b/web/regression/feature_utils/pgadmin_page.py @@ -48,6 +48,9 @@ class PgadminPage: self.click_modal('OK') self.wait_for_reloading_indicator_to_disappear() + def refresh_page(self): + self.driver.refresh() + def click_modal(self, button_text): time.sleep(0.5) # Find active alertify dialog in case of multiple alertify dialog @@ -85,8 +88,7 @@ class PgadminPage: self.driver.find_element_by_link_text("Tools").click() tools_menu = self.driver.find_element_by_id('mnu_tools') - # Query Tool is first li - query_tool = tools_menu.find_element_by_tag_name('li') + query_tool = tools_menu.find_element_by_id('query_tool') self.enable_menu_item(query_tool, 10) @@ -98,11 +100,11 @@ class PgadminPage: # wait until menu becomes enabled. while time.time() - start_time < wait_time: # wait_time seconds # if menu is disabled then it will have - # two classes 'menu-item disabled'. + # two classes 'dropdown-item disabled'. # And if menu is enabled the it will have - # only one class 'menu-item'. + # only one class 'dropdown-item'. - if 'menu-item' == str(menu_item.get_attribute('class')): + if 'dropdown-item' == str(menu_item.get_attribute('class')): break time.sleep(0.1) else: @@ -136,6 +138,8 @@ class PgadminPage: server_to_remove = self.find_by_xpath( "//*[@id='tree']//*[.='" + server_config['name'] + "' and @class='aciTreeItem']") + self.driver.execute_script( + "arguments[0].scrollIntoView()", server_to_remove) self.click_element(server_to_remove) object_menu_item = self.find_by_partial_link_text("Object") self.click_element(object_menu_item) @@ -144,14 +148,19 @@ class PgadminPage: self.click_modal('OK') def select_tree_item(self, tree_item_text): - self.find_by_xpath( + item = self.find_by_xpath( "//*[@id='tree']//*[.='" + tree_item_text + - "' and @class='aciTreeItem']").click() + "' and @class='aciTreeItem']") + self.driver.execute_script("arguments[0].scrollIntoView()", item) + item.click() def toggle_open_tree_item(self, tree_item_text): - self.find_by_xpath( + item = self.find_by_xpath( "//*[@id='tree']//*[.='" + tree_item_text + - "']/../*[@class='aciTreeButton']").click() + "']/../*[@class='aciTreeButton']") + + self.driver.execute_script("arguments[0].scrollIntoView()", item) + item.click() def toggle_open_server(self, tree_item_text): def check_for_password_dialog_or_tree_open(driver): @@ -276,11 +285,12 @@ class PgadminPage: try: element = find_method_with_args(driver) if element.is_displayed() and element.is_enabled(): - return element + return True except NoSuchElementException: return False - return self._wait_for("element to exist", element_if_it_exists) + self._wait_for("element to exist", element_if_it_exists) + return find_method_with_args(self.driver) def wait_for_element_to_disappear(self, find_method_with_args): def element_if_it_disappears(driver): diff --git a/web/regression/python_test_utils/test_utils.py b/web/regression/python_test_utils/test_utils.py index 51d54e2de..beeb6322a 100644 --- a/web/regression/python_test_utils/test_utils.py +++ b/web/regression/python_test_utils/test_utils.py @@ -435,6 +435,7 @@ def create_server(server): ' comment) VALUES (?,?,?,?,?,?,?,?,?,?)', server_details) server_id = cur.lastrowid conn.commit() + conn.close() # Add server info to parent_node_dict regression.parent_node_dict["server"].append( { @@ -639,6 +640,50 @@ def set_preference(default_binary_path): ) conn.commit() + conn.close() + + +def disable_tree_state_save(): + conn = sqlite3.connect(config.TEST_SQLITE_PATH) + cur = conn.cursor() + pref = Preferences.module('browser')\ + .preference('browser_tree_state_save_interval') + + user_pref = cur.execute( + 'SELECT pid, uid FROM user_preferences ' + 'where pid=?', (pref.pid,) + ) + + if len(user_pref.fetchall()) == 0: + cur.execute( + 'INSERT INTO user_preferences(pid, uid, value)' + ' VALUES (?,?,?)', (pref.pid, 1, -1) + ) + else: + cur.execute( + 'UPDATE user_preferences' + ' SET VALUE = ?' + ' WHERE PID = ?', (-1, pref.pid) + ) + conn.commit() + conn.close() + + +def reset_layout_db(user_id=None): + conn = sqlite3.connect(config.TEST_SQLITE_PATH) + cur = conn.cursor() + + if user_id is None: + cur.execute( + 'DELETE FROM SETTING WHERE SETTING="Browser/Layout"' + ) + else: + cur.execute( + 'DELETE FROM SETTING WHERE SETTING="Browser/Layout"' + ' AND USER_ID=?', user_id + ) + conn.commit() + conn.close() def remove_db_file(): diff --git a/web/regression/runtests.py b/web/regression/runtests.py index ceb7858d6..a52c5a471 100644 --- a/web/regression/runtests.py +++ b/web/regression/runtests.py @@ -419,6 +419,9 @@ if __name__ == '__main__': if server['default_binary_paths'] is not None: test_utils.set_preference(server['default_binary_paths']) + # Disable tree state saving + test_utils.disable_tree_state_save() + suite = get_suite(test_module_list, server, test_client,