diff --git a/web/pgadmin/feature_tests/file_manager_test.py b/web/pgadmin/feature_tests/file_manager_test.py
index c76f20386..6e4f52e1d 100644
--- a/web/pgadmin/feature_tests/file_manager_test.py
+++ b/web/pgadmin/feature_tests/file_manager_test.py
@@ -15,6 +15,7 @@ import time
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
+from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import StaleElementReferenceException, \
TimeoutException
from regression.feature_utils.base_feature_test import BaseFeatureTest
@@ -83,7 +84,7 @@ class CheckFileManagerFeatureTest(BaseFeatureTest):
self.page.find_by_css_selector('.change_file_types')
self.page.fill_input_by_css_selector(
QueryToolLocators.input_file_path_css,
- "/tmp/", key_after_input=Keys.RETURN)
+ "/tmp", key_after_input=Keys.RETURN)
if self.page.driver.capabilities['browserName'] == 'firefox':
table = self.page.wait_for_element_to_reload(
@@ -91,6 +92,12 @@ class CheckFileManagerFeatureTest(BaseFeatureTest):
QueryToolLocators.select_file_content_css)
)
else:
+ self.wait.until(EC.visibility_of_element_located(
+ (By.CSS_SELECTOR, QueryToolLocators.select_file_content_css)))
+ self.wait.until(lambda element:
+ self.page.driver.find_element_by_css_selector(
+ '[name=home]').is_enabled())
+
table = self.page.driver.find_element_by_css_selector(
QueryToolLocators.select_file_content_css)
retry_count = 0
@@ -113,7 +120,8 @@ class CheckFileManagerFeatureTest(BaseFeatureTest):
# For XSS we need to search against element's html code
assert source_code.find(
string_to_find
- ) != -1, "{0} might be vulnerable to XSS ".format(source)
+ ) != -1, "{0} might be vulnerable to XSS, source code is: {1}".format(
+ source, source_code)
def _check_file_sorting(self):
load_file = self.page.find_by_css_selector(
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 cc2e89b59..5ae86734c 100644
--- a/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
+++ b/web/pgadmin/feature_tests/pg_utilities_backup_restore_test.py
@@ -108,16 +108,17 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
status = test_utils.get_watcher_dialogue_status(self)
- if status != "Successfully completed.":
- test_gui_helper.close_bgprocess_popup(self)
-
- self.assertEquals(status, "Successfully completed.")
-
self.page.retry_click(
(By.CSS_SELECTOR,
NavMenuLocators.status_alertifier_more_btn_css),
(By.XPATH,
NavMenuLocators.process_watcher_alertfier))
+ self.page.wait_for_element_to_disappear(
+ lambda driver: driver.find_element_by_css_selector(".loading-logs")
+ )
+
+ if status != "Successfully completed.":
+ self.assertEquals(status, "Successfully completed.")
backup_file = None
# Check for XSS in Backup details
@@ -177,16 +178,17 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
status = test_utils.get_watcher_dialogue_status(self)
- if status != "Successfully completed.":
- test_gui_helper.close_bgprocess_popup(self)
-
- self.assertEquals(status, "Successfully completed.")
-
self.page.retry_click(
(By.CSS_SELECTOR,
NavMenuLocators.status_alertifier_more_btn_css),
(By.XPATH,
NavMenuLocators.process_watcher_alertfier))
+ self.page.wait_for_element_to_disappear(
+ lambda driver: driver.find_element_by_css_selector(".loading-logs")
+ )
+
+ if status != "Successfully completed.":
+ self.assertEquals(status, "Successfully completed.")
# Check for XSS in Restore details
if self.is_xss_check:
diff --git a/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
index 728323b49..0e6586d0e 100644
--- a/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
+++ b/web/pgadmin/feature_tests/pg_utilities_maintenance_test.py
@@ -26,19 +26,19 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
scenarios = [
("Test for PG maintenance: database", dict(
- database_name='pg_maintenance',
- table_name='pg_maintenance_table',
+ database_name='pg_maintenance_',
+ table_name='table_',
test_level='database',
is_xss_check=False,
)),
("Test for PG maintenance: table", dict(
- database_name='pg_maintenance',
- table_name='pg_maintenance_table',
+ database_name='pg_maintenance_',
+ table_name='table_',
test_level='table',
is_xss_check=False,
)),
("Test for XSS in maintenance dialog", dict(
- database_name='pg_maintenance',
+ database_name='pg_maintenance_',
table_name='
test_me
',
test_level='table',
is_xss_check=True,
@@ -67,7 +67,9 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
self.server['sslmode']
)
- self.table_name = self.table_name + str(random.randint(1000, 3000))
+ self.table_name = self.table_name + str(random.randint(100, 1000))
+ self.database_name = \
+ self.database_name + str(random.randint(100, 1000))
test_utils.drop_database(connection, self.database_name)
test_utils.create_database(self.server, self.database_name)
test_utils.create_table(self.server, self.database_name,
@@ -87,7 +89,6 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
self.wait.until(EC.visibility_of_element_located(
(By.CSS_SELECTOR,
NavMenuLocators.bcg_process_status_alertifier_css)))
-
self.verify_command()
def _open_maintenance_dialogue(self):
@@ -101,9 +102,18 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
self.page.toggle_open_tables_node(self.server['name'],
self.server['db_password'],
self.database_name, 'public')
- self.page.click_a_tree_node(
- self.table_name,
- TreeAreaLocators.sub_nodes_of_tables_node)
+ retry = 5
+ status = False
+ while retry > 0:
+ status = self.page.click_a_tree_node(
+ self.table_name,
+ TreeAreaLocators.sub_nodes_of_tables_node)
+ if status:
+ break
+ else:
+ retry -= 1
+ self.assertTrue(status, "Table name {} is not selected".format(
+ self.table_name))
self.page.retry_click(
(By.LINK_TEXT,
@@ -118,17 +128,17 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
def verify_command(self):
status = test_utils.get_watcher_dialogue_status(self)
- if status != "Successfully completed.":
-
- test_gui_helper.close_bgprocess_popup(self)
-
- self.assertEquals(status, "Successfully completed.")
-
self.page.retry_click(
(By.CSS_SELECTOR,
NavMenuLocators.status_alertifier_more_btn_css),
(By.XPATH,
NavMenuLocators.process_watcher_alertfier))
+ self.page.wait_for_element_to_disappear(
+ lambda driver: driver.find_element_by_css_selector(".loading-logs")
+ )
+
+ if status != "Successfully completed.":
+ self.assertEquals(status, "Successfully completed.")
command = self.page.find_by_css_selector(
NavMenuLocators.
@@ -158,9 +168,9 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
def after(self):
test_gui_helper.close_bgprocess_popup(self)
- self.page.remove_server(self.server)
test_utils.delete_table(self.server, self.database_name,
self.table_name)
+ self.page.remove_server(self.server)
connection = test_utils.get_db_connection(
self.server['db'],
self.server['username'],
diff --git a/web/pgadmin/feature_tests/query_tool_tests.py b/web/pgadmin/feature_tests/query_tool_tests.py
index 3bcc5e8e4..a0f350320 100644
--- a/web/pgadmin/feature_tests/query_tool_tests.py
+++ b/web/pgadmin/feature_tests/query_tool_tests.py
@@ -135,18 +135,10 @@ class QueryToolFeatureTest(BaseFeatureTest):
query_op.click()
# disable auto rollback only if they are enabled
- btn = self.page.find_by_css_selector(
- QueryToolLocators.btn_auto_rollback)
- check = btn.find_element_by_tag_name('i')
- if 'visibility-hidden' not in check.get_attribute('class'):
- btn.click()
+ self.uncheck_execute_option('auto_rollback')
# enable autocommit only if it's disabled
- btn = self.page.find_by_css_selector(
- QueryToolLocators.btn_auto_commit)
- check = btn.find_element_by_tag_name('i')
- if 'visibility-hidden' in check.get_attribute('class'):
- btn.click()
+ self.check_execute_option('auto_commit')
# close menu
query_op.click()
@@ -181,8 +173,7 @@ SELECT generate_series(1, {}) as id1, 'dummy' as id2""".format(
print("On demand result set on grid select all... ",
file=sys.stderr, end="")
- self.page.find_by_css_selector(
- QueryToolLocators.btn_execute_query_css).click()
+ self.page.click_execute_query_button()
# wait for header of the table to be visible
canvas = self.page.find_by_css_selector(
@@ -213,8 +204,7 @@ SELECT generate_series(1, {}) as id1, 'dummy' as id2""".format(
print("On demand result set on column select all... ",
file=sys.stderr, end="")
- self.page.find_by_css_selector(
- QueryToolLocators.btn_execute_query_css).click()
+ self.page.click_execute_query_button()
self.page.wait_for_query_tool_loading_indicator_to_disappear()
@@ -349,18 +339,16 @@ CREATE TABLE public.{}();""".format(table_name)
self.page.fill_codemirror_area_with(query)
- # open auto commit option and disable it
+ # disable auto commit option
query_op = self.page.find_by_css_selector(
QueryToolLocators.btn_query_dropdown)
query_op.click()
- self.page.find_by_css_selector(
- QueryToolLocators.btn_auto_commit).click()
+ self.uncheck_execute_option('auto_commit')
# close option
query_op.click()
# execute query
- self.page.find_by_css_selector(
- QueryToolLocators.btn_execute_query_css).click()
+ self.page.click_execute_query_button()
self.page.wait_for_query_tool_loading_indicator_to_disappear()
self.page.click_tab('Messages')
@@ -424,13 +412,12 @@ END;"""
QueryToolLocators.btn_query_dropdown)
query_op.click()
- self.page.find_by_css_selector(
- QueryToolLocators.btn_auto_commit).click()
+ # Enable auto_commit if it is disabled
+ self.check_execute_option('auto_commit')
query_op.click()
- self.page.find_by_css_selector(
- QueryToolLocators.btn_execute_query_css).click()
+ self.page.click_execute_query_button()
self.page.wait_for_query_tool_loading_indicator_to_disappear()
@@ -504,14 +491,13 @@ END;"""
QueryToolLocators.btn_query_dropdown)
query_op.click()
- # uncheckt auto commit and check auto-rollback
+ # uncheck auto commit and check auto-rollback
self.uncheck_execute_option('auto_commit')
self.check_execute_option('auto_rollback')
query_op.click()
- self.page.find_by_css_selector(
- QueryToolLocators.btn_execute_query_css).click()
+ self.page.click_execute_query_button()
self.page.wait_for_query_tool_loading_indicator_to_disappear()
self.page.clear_query_tool()
@@ -606,11 +592,20 @@ SELECT 1, pg_sleep(300)"""
self.uncheck_execute_option('auto_rollback')
# close drop down
query_op.click()
+ # Execute query
+ retry = 5
+ execute_button = self.page.find_by_css_selector(
+ QueryToolLocators.btn_execute_query_css)
+ while retry > 0:
+ execute_button.click()
+ if self.page.wait_for_query_tool_loading_indicator_to_appear():
+ break
+ else:
+ retry -= 1
+ # Providing a second of sleep since clicks on the execute and stop
+ # query button is too quick that the query is not able run properly
+ time.sleep(1)
- self.page.find_by_css_selector(
- QueryToolLocators.btn_execute_query_css).click()
-
- self.page.find_by_xpath("//*[@id='fetching_data']")
self.page.find_by_css_selector(
QueryToolLocators.btn_cancel_query).click()
self.page.wait_for_query_tool_loading_indicator_to_disappear()
diff --git a/web/pgadmin/feature_tests/view_data_dml_queries.py b/web/pgadmin/feature_tests/view_data_dml_queries.py
index 02a449971..14591cdae 100644
--- a/web/pgadmin/feature_tests/view_data_dml_queries.py
+++ b/web/pgadmin/feature_tests/view_data_dml_queries.py
@@ -308,7 +308,11 @@ CREATE TABLE public.nonintpkey
self._verify_row_data(False, updated_row_data)
def _add_update_save_row(self, data, row=1):
- for idx in data.keys():
+ items = list(data.keys())
+ for item in range(0, len(items)):
+ items[item] = int(items[item])
+ items.sort(reverse=False)
+ for idx in items:
cell_xpath = CheckForViewDataTest._get_cell_xpath(
'r' + str(idx), row
)
@@ -347,9 +351,21 @@ CREATE TABLE public.nonintpkey
result_row = self.page.find_by_xpath(xpath)
- # List of row values in an array
- for idx in config_check_data.keys():
- element = result_row.find_element_by_class_name("r" + str(idx))
+ # Verify the List of actual values with the expected list
+ actual_list = list(config_check_data.keys())
+ for value in range(0, len(actual_list)):
+ actual_list[value] = int(actual_list[value])
+ actual_list.sort(reverse=False)
+ retry = 5
+ for idx in actual_list:
+ while retry > 0:
+ try:
+ element = \
+ result_row.find_element_by_class_name("r" + str(idx))
+ break
+ except Exception:
+ print("stale reference exception at id:", idx)
+ retry -= 1
self.page.driver.execute_script(
"arguments[0].scrollIntoView(false)", element)
time.sleep(0.4)
diff --git a/web/regression/feature_utils/pgadmin_page.py b/web/regression/feature_utils/pgadmin_page.py
index a1735b152..61aa4cf5a 100644
--- a/web/regression/feature_utils/pgadmin_page.py
+++ b/web/regression/feature_utils/pgadmin_page.py
@@ -176,6 +176,18 @@ class PgadminPage:
execute_button.click()
self.wait_for_query_tool_loading_indicator_to_disappear()
+ def click_execute_query_button(self):
+ retry = 5
+ execute_button = self.find_by_css_selector(
+ QueryToolLocators.btn_execute_query_css)
+ while retry > 0:
+ execute_button.click()
+ if self.wait_for_query_tool_loading_indicator_to_appear():
+ break
+ else:
+ retry -= 1
+ self.wait_for_query_tool_loading_indicator_to_disappear()
+
def check_execute_option(self, option):
""""This function will check auto commit or auto roll back based on
user input. If button is already checked, no action will be taken"""
@@ -394,6 +406,7 @@ class PgadminPage:
name_of_database):
"""will expand database node under databases node"""
db_node_expanded_status = False
+ retry = 5
if self.expand_databases_node(server_name, server_password):
sub_nodes_of_databases_node = self.find_by_xpath_list(
TreeAreaLocators.sub_nodes_of_databases_node(server_name))
@@ -410,9 +423,17 @@ class PgadminPage:
self.driver.execute_script("arguments[0].scrollIntoView()",
sub_nodes_of_databases_node[
index_of_required_db_node])
- webdriver.ActionChains(self.driver).double_click(
- sub_nodes_of_databases_node[
- index_of_required_db_node]).perform()
+ while retry > 0:
+ webdriver.ActionChains(self.driver).double_click(
+ sub_nodes_of_databases_node[
+ index_of_required_db_node]).perform()
+ if self.check_if_element_exist_by_xpath(
+ "//div[@class='ajs-header'and text()='INTERNAL SERVER "
+ "ERROR']", 1):
+ self.click_modal('OK')
+ retry -= 1
+ else:
+ break
if self.wait_for_elements_to_appear(
self.driver, TreeAreaLocators.
sub_nodes_of_database_node(
@@ -935,7 +956,7 @@ class PgadminPage:
return False
return True
- except NoSuchElementException:
+ except (NoSuchElementException, StaleElementReferenceException):
return True
return self._wait_for("element to disappear", element_if_it_disappears)
@@ -976,9 +997,10 @@ class PgadminPage:
self._wait_for("spinner to disappear", spinner_has_disappeared, 20)
def wait_for_query_tool_loading_indicator_to_appear(self):
- self.check_if_element_exist_by_xpath(
+ status = self.check_if_element_exist_by_xpath(
"//div[@id='editor-panel']//"
- "div[@class='pg-sp-container sql-editor-busy-fetching']")
+ "div[@class='pg-sp-container sql-editor-busy-fetching']", 1)
+ return status
def wait_for_app(self):
def page_shows_app(driver):
diff --git a/web/regression/runtests.py b/web/regression/runtests.py
index 540eae65e..8c52753f3 100644
--- a/web/regression/runtests.py
+++ b/web/regression/runtests.py
@@ -234,6 +234,8 @@ def get_test_modules(arguments):
if 'headless_chrome' in test_setup.config_data:
if test_setup.config_data['headless_chrome']:
options.add_argument("--headless")
+ options.add_argument("--no-sandbox")
+ options.add_argument("--disable-setuid-sandbox")
options.add_argument("--window-size=1280,1024")
options.add_argument("--disable-infobars")
options.add_experimental_option('w3c', False)