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 1c89393d..4e11f994 100644 --- a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py +++ b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py @@ -83,6 +83,7 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest): self.page.find_by_css_selector( ".pg-bg-more-details").click() + backup_file = None # Check for XSS in Backup details if self.is_xss_check: self._check_detailed_window_for_xss('Backup') @@ -99,7 +100,6 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest): self.assertIn("pg_dump", str(command)) - backup_file = None if command: backup_file = command[int(command.find('--file')) + 8:int(command.find('--host')) - 2] diff --git a/web/pgadmin/feature_tests/view_data_dml_queries.py b/web/pgadmin/feature_tests/view_data_dml_queries.py index 1be9dcfa..36d224a8 100644 --- a/web/pgadmin/feature_tests/view_data_dml_queries.py +++ b/web/pgadmin/feature_tests/view_data_dml_queries.py @@ -309,6 +309,7 @@ CREATE TABLE public.defaults_{0} if (idx != 1 and not is_new_row) or is_new_row: self.assertEquals(element.text, config_data[str(idx)][1]) + self.assertEquals(element.text, config_data[str(idx)][1]) # scroll browser back to the left # to reset position so other assertions can succeed diff --git a/web/pgadmin/feature_tests/xss_checks_panels_and_query_tool_test.py b/web/pgadmin/feature_tests/xss_checks_panels_and_query_tool_test.py index 27ac8c2c..365d109b 100644 --- a/web/pgadmin/feature_tests/xss_checks_panels_and_query_tool_test.py +++ b/web/pgadmin/feature_tests/xss_checks_panels_and_query_tool_test.py @@ -55,10 +55,12 @@ class CheckForXssFeatureTest(BaseFeatureTest): self._check_xss_in_dependents_tab() # Query tool + self.page.open_query_tool() self._check_xss_in_query_tool() self.page.close_query_tool() # Explain module + self.page.open_query_tool() self._check_xss_in_explain_module() self.page.close_query_tool() @@ -142,17 +144,11 @@ class CheckForXssFeatureTest(BaseFeatureTest): "Dependents tab (BackGrid)" ) - def _open_query_tool(self): - self.page.driver.find_element_by_link_text("Tools").click() - self.page.find_by_partial_link_text("Query Tool").click() - self.page.click_tab('Query -') - def _check_xss_in_query_tool(self): print( "\n\tChecking the SlickGrid cell for the XSS", file=sys.stderr, end="" ) - self._open_query_tool() self.page.fill_codemirror_area_with( "select ''" ) @@ -179,14 +175,10 @@ class CheckForXssFeatureTest(BaseFeatureTest): "\n\tChecking the Graphical Explain plan for the XSS ...", file=sys.stderr, end="" ) - self._open_query_tool() self.page.fill_codemirror_area_with( 'select * from "{0}"'.format(self.test_table_name) ) - query_op = self.page.find_by_id("btn-query-dropdown") - query_op.click() - self.page.find_by_id("btn-explain").click() self.page.wait_for_query_tool_loading_indicator_to_disappear() self.page.click_tab('Explain') diff --git a/web/pgadmin/tools/datagrid/static/js/datagrid.js b/web/pgadmin/tools/datagrid/static/js/datagrid.js index df16d0bb..259d2a2a 100644 --- a/web/pgadmin/tools/datagrid/static/js/datagrid.js +++ b/web/pgadmin/tools/datagrid/static/js/datagrid.js @@ -54,14 +54,7 @@ define('pgadmin.datagrid', [ self.preferences = pgBrowser.get_preferences_for_module('sqleditor'); }); - this.spinner_el = - `
-
-
-
-
-
-
`; + // Define list of nodes on which view data option appears var supported_nodes = [ 'table', 'view', 'mview', @@ -514,17 +507,26 @@ define('pgadmin.datagrid', [ var openQueryToolURL = function(j) { // add spinner element - $(j).data('embeddedFrame').$container.append(pgAdmin.DataGrid.spinner_el); - setTimeout(function() { + let $spinner_el = + $(`
+
+
+
+
+
+
`).appendTo($(j).data('embeddedFrame').$container); + + let init_poller_id = setInterval(function() { var frameInitialized = $(j).data('frameInitialized'); if (frameInitialized) { + clearInterval(init_poller_id); var frame = $(j).data('embeddedFrame'); if (frame) { + frame.onLoaded(()=>{ + $spinner_el.remove(); + }); frame.openURL(baseUrl); - frame.$container.find('.pg-sp-container').delay(1000).hide(1); } - } else { - openQueryToolURL(j); } }, 100); }; diff --git a/web/pgadmin/utils/route.py b/web/pgadmin/utils/route.py index e67f0195..b206cb2e 100644 --- a/web/pgadmin/utils/route.py +++ b/web/pgadmin/utils/route.py @@ -53,7 +53,7 @@ class TestsGeneratorRegistry(ABCMeta): ABCMeta.__init__(cls, name, bases, d) @classmethod - def load_generators(cls, pkg_root, exclude_pkgs): + def load_generators(cls, pkg_root, exclude_pkgs, for_modules=[]): cls.registry = dict() @@ -61,6 +61,13 @@ class TestsGeneratorRegistry(ABCMeta): all_modules += find_modules(pkg_root, False, True) + # If specific modules are to be tested, exclude others + if len(for_modules) > 0: + all_modules = [module_name + for module_name in all_modules + for fmod in for_modules + if module_name.endswith(fmod)] + # Check for SERVER mode for module_name in all_modules: try: diff --git a/web/regression/README b/web/regression/README index 7e668cfd..6a68d36f 100644 --- a/web/regression/README +++ b/web/regression/README @@ -167,6 +167,14 @@ Python Tests: Example 2) Run test framework for 'database' node run 'python runtests.py --pkg browser.server_groups.servers.databases.tests' +- Execute test framework for certain modules of a test pkg + + Example 1) Run test framework for 'sqleditor' package and test_start_running_query module + run 'python runtests.py --pkg tools.sqleditor --modules test_start_running_query' + + Example 2) Run test framework for 'sqleditor' package and test_start_running_query,test_query_tool_fs_utils modules + run 'python runtests.py --pkg tools.sqleditor --modules test_start_running_query,test_query_tool_fs_utils' + - Exclude a package and its subpackages when running tests: Example: exclude feature tests but run all others: diff --git a/web/regression/feature_utils/pgadmin_page.py b/web/regression/feature_utils/pgadmin_page.py index 0c8f0fa3..1fb525ee 100644 --- a/web/regression/feature_utils/pgadmin_page.py +++ b/web/regression/feature_utils/pgadmin_page.py @@ -94,6 +94,7 @@ class PgadminPage: self.find_by_partial_link_text("Query Tool").click() self.click_tab('Query -') + self.find_by_css_selector('iframe') def enable_menu_item(self, menu_item, wait_time): start_time = time.time() @@ -224,38 +225,60 @@ class PgadminPage: "clicking the element not to throw an exception", click_succeeded ) - def fill_input_by_field_name(self, field_name, field_content): - field = self.find_by_xpath("//input[@name='" + field_name + "']") + def fill_input_by_field_name(self, field_name, field_content, + input_keys=False): + field = self.find_by_css_selector( + "input[name='" + field_name + "']:not(:disabled)") backspaces = [Keys.BACKSPACE] * len(field.get_attribute('value')) field.click() - field.send_keys(backspaces) - field.send_keys(str(field_content)) - self.wait_for_input_field_content(field_name, field_content) - def fill_codemirror_area_with(self, field_content): + # Use send keys if input_keys true, else use javascript to set content + if input_keys: + field.send_keys(backspaces) + field.send_keys(str(field_content)) + self.wait_for_input_field_content(field_name, field_content) + else: + self.driver.execute_script( + "arguments[0].setAttribute('value', arguments[1])", + field, field_content) + + action = ActionChains(self.driver) + action.key_down(Keys.ARROW_DOWN) + action.perform() + + def fill_codemirror_area_with(self, field_content, input_keys=False): def find_codemirror(driver): try: driver.switch_to.default_content() driver.switch_to_frame( driver.find_element_by_tag_name("iframe")) - element = driver.find_element_by_xpath( - "//pre[contains(@class,'CodeMirror-line')]/../../../" - "*[contains(@class,'CodeMirror-code')]") + element = driver.find_element_by_css_selector( + "#output-panel .CodeMirror") if element.is_displayed() and element.is_enabled(): return element except (NoSuchElementException, WebDriverException): return False + codemirror_ele = WebDriverWait( + self.driver, timeout=self.timeout, poll_frequency=0.01)\ + .until(find_codemirror, + "Timed out waiting for codemirror to appear") + time.sleep(1) - WebDriverWait(self.driver, timeout=self.timeout, poll_frequency=0.01).\ - until(find_codemirror, "Timed out waiting for codemirror " - "to appear").click() - time.sleep(1) + codemirror_ele.click() - action = ActionChains(self.driver) - action.send_keys(field_content) - action.perform() + # Use send keys if input_keys true, else use javascript to set content + if input_keys: + action = ActionChains(self.driver) + action.send_keys(field_content) + action.perform() + else: + self.driver.execute_script( + "arguments[0].CodeMirror.setValue(arguments[1]);" + "arguments[0].CodeMirror.setCursor(" + "arguments[0].CodeMirror.lineCount(),0);", + codemirror_ele, field_content) def click_tab(self, tab_name): WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable( @@ -329,10 +352,10 @@ class PgadminPage: def wait_for_query_tool_loading_indicator_to_disappear(self): def spinner_has_disappeared(driver): try: - driver.find_element_by_xpath( - "//*[@id='fetching_data' and @class='hide']" + spinner = driver.find_element_by_css_selector( + "#editor-panel .pg-sp-container" ) - return False + return "d-none" in spinner.get_attribute("class") except NoSuchElementException: # wait for loading indicator disappear animation to complete. time.sleep(0.5) diff --git a/web/regression/runtests.py b/web/regression/runtests.py index 48d3749f..6f95370f 100644 --- a/web/regression/runtests.py +++ b/web/regression/runtests.py @@ -230,9 +230,14 @@ def get_test_modules(arguments): if arguments['pkg'] is None or arguments['pkg'] == "all": TestsGeneratorRegistry.load_generators('pgadmin', exclude_pkgs) else: + for_modules = [] + if arguments['modules'] is not None: + for_modules = arguments['modules'].split(',') + TestsGeneratorRegistry.load_generators('pgadmin.%s' % arguments['pkg'], - exclude_pkgs) + exclude_pkgs, + for_modules) # Sort module list so that test suite executes the test cases sequentially module_list = TestsGeneratorRegistry.registry.items() @@ -263,6 +268,10 @@ def add_arguments(): '--default_browser', help='Executes the feature test in specific browser' ) + parser.add_argument( + '--modules', + help='Executes the feature test for specific modules in pkg' + ) arg = parser.parse_args() return arg