Feature test stabilisation.

pull/23/head
Usman Muzaffar 2019-05-23 09:31:52 +01:00 committed by Dave Page
parent ee37be56f9
commit dcd163ac02
8 changed files with 169 additions and 24 deletions

View File

@ -67,9 +67,9 @@ class CheckFileManagerFeatureTest(BaseFeatureTest):
def _create_new_file(self):
self.page.find_by_css_selector(QueryToolLocatorsCss.btn_save).click()
# Set the XSS value in input
print('Create file')
self.page.find_by_css_selector('.change_file_types')
self.page.fill_input_by_css_selector("#file-input-path", self.XSS_FILE)
self.page.fill_input_by_css_selector("input#file-input-path",
self.XSS_FILE)
# Save the file
self.page.click_modal('Create')
self.page.wait_for_query_tool_loading_indicator_to_disappear()

View File

@ -53,6 +53,8 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
self.wait = WebDriverWait(self.page.driver, 20)
test_gui_helper.close_bgprocess_popup(self)
def runTest(self):
self.page.toggle_open_server(self.server['name'])
self.page.toggle_open_tree_item('Databases')
@ -68,7 +70,6 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
self.wait.until(EC.element_to_be_clickable(
(By.CSS_SELECTOR, ".file [name='file']"))).click()
# .input-group-append >button
self.page.fill_input_by_field_name(
"file", "test_backup", loose_focus=True)
@ -77,11 +78,10 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
self.page.find_by_css_selector('.ajs-bg-bgprocess')
# status = self.page.find_by_css_selector(
# ".pg-bg-status .bg-success-light .pg-bg-status-text").text
status = test_utils.get_watcher_dialogue_status(self)
status = self.page.find_by_css_selector(
".pg-bg-status-text").text
if status != "Successfully completed.":
test_gui_helper.close_bgprocess_popup(self)
self.assertEquals(status, "Successfully completed.")
@ -130,8 +130,11 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
self.page.find_by_css_selector('.ajs-bg-bgprocess')
status = self.page.find_by_css_selector(
".pg-bg-status-text").text
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.find_by_css_selector(
@ -158,7 +161,6 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
os.remove(backup_file)
def after(self):
test_gui_helper.close_bgprocess_popup(self)
self.page.remove_server(self.server)
connection = test_utils.get_db_connection(
self.server['db'],

View File

@ -61,6 +61,7 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
self.table_name)
self.page.add_server(self.server)
self.wait = WebDriverWait(self.page.driver, 20)
test_gui_helper.close_bgprocess_popup(self)
def runTest(self):
self._open_maintenance_dialogue()
@ -75,7 +76,7 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
if self.test_level == 'table':
self.page.toggle_open_tree_item('Schemas')
self.page.toggle_open_tree_item('public')
self.page.toggle_open_tree_item('Tables')
self.page.toggle_open_tables_node()
self.page.select_tree_item(self.table_name)
self.driver.find_element_by_link_text("Tools").click()
@ -83,8 +84,10 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
time.sleep(0.5)
def _verify_command(self):
status = self.page.find_by_css_selector(
".pg-bg-status-text").text
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.find_by_css_selector(".pg-bg-more-details").click()
command = self.page.find_by_css_selector(
@ -113,7 +116,6 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
"div.wcFloatingFocus div.fa-close").click()
def after(self):
test_gui_helper.close_bgprocess_popup(self)
self.page.remove_server(self.server)
connection = test_utils.get_db_connection(
self.server['db'],

View File

@ -36,6 +36,10 @@ class CheckDebuggerForXssFeatureTest(BaseFeatureTest):
self.server, "postgres", "a_test_function"
)
if test_utils.does_function_exist(self.server, 'postgres',
'a_test_function') != 'True':
raise Exception("The required function is not found")
def runTest(self):
self.page.wait_for_spinner_to_disappear()
self.page.add_server(self.server)
@ -53,7 +57,7 @@ class CheckDebuggerForXssFeatureTest(BaseFeatureTest):
self.page.toggle_open_tree_item('postgres')
self.page.toggle_open_tree_item('Schemas')
self.page.toggle_open_tree_item('public')
self.page.toggle_open_tree_item('Functions')
self.page.toggle_open_function_node()
self.page.select_tree_item("a_test_function()")
def _debug_function(self):

View File

@ -58,7 +58,8 @@ class CheckRoleMembershipControlFeatureTest(BaseFeatureTest):
def _check_role_membership_control(self):
self.page.driver.find_element_by_link_text("Object").click()
self.page.driver.find_element_by_link_text("Properties...").click()
self.page.find_by_partial_link_text("Membership").click()
# self.page.find_by_partial_link_text("Membership").click()
self.click_membership_tab()
# Fetch the source code for our custom control
source_code = self.page.find_by_xpath(
"//div[contains(@class,'rolmembership')]"
@ -78,3 +79,19 @@ class CheckRoleMembershipControlFeatureTest(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)
def click_membership_tab(self):
"""This will click and open membership tab of role"""
success = False
attempts = 3
while not success and attempts > 0:
membership_tab_link = self.page.find_by_xpath(
"//a[normalize-space(text())='Membership']")
membership_tab_link.click()
try:
self.page.find_by_xpath("//input[@placeholder="
"'Select members']")
break
except Exception as e:
attempts -= 1
pass

View File

@ -9,6 +9,7 @@
import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException, \
WebDriverException, TimeoutException, NoSuchWindowException, \
StaleElementReferenceException
@ -71,7 +72,8 @@ class PgadminPage:
.perform()
self.find_by_partial_link_text("Server...").click()
self.fill_input_by_field_name("name", server_config['name'])
self.fill_input_by_field_name("name", server_config['name'],
loose_focus=True)
self.find_by_partial_link_text("Connection").click()
self.fill_input_by_field_name("host", server_config['host'])
self.fill_input_by_field_name("port", server_config['port'])
@ -151,7 +153,18 @@ class PgadminPage:
"//*[@id='tree']//*[contains(text(), '" + tree_item_text + "')]"
"/parent::span[@class='aciTreeItem']")
self.driver.execute_script("arguments[0].scrollIntoView()", item)
item.click()
# unexpected exception like element overlapping, click attempts more
# than one time
attempts = 3
while attempts > 0:
try:
item.click()
break
except Exception as e:
attempts -= 1
time.sleep(.4)
if attempts == 0:
raise Exception(e)
def toggle_open_servers_group(self):
"""This will open Servers group to display underlying nodes"""
@ -197,13 +210,66 @@ class PgadminPage:
"='Tables']]]/span[@class='aciTreeButton']")
ActionChains(self.driver).click(item_button).perform()
def toggle_open_function_node(self):
"""The function will be used for opening Functions node only"""
node_expanded = False
attempts = 3
xpath_for_functions_node = \
"//span[@class='aciTreeText' and starts-with(text()," \
"'Functions')]"
xpath_for_exp = "//div[div[div[div[div[div[div[div[span[span[" \
"(@class='aciTreeText') and starts-with(text()," \
"'Functions')]]]]]]]]]]"
xpath_for_button = "//div[span[span[(@class='aciTreeText') " \
"and starts-with(text(),'Functions')]]]" \
"/span[@class='aciTreeButton']"
while node_expanded is not True and attempts > 0:
# get the element which contains 'aria-expanded' info
xpath_for_refresh_btn = "//li[@class='context-menu-item']" \
"/span[text()='Refresh...']"
# add code to refresh button, sometime the the collapsing button
# is not visible even if there is sub node.
functions_node_ele = self.find_by_xpath(xpath_for_functions_node)
webdriver.ActionChains(self.driver).move_to_element(
functions_node_ele).context_click().perform()
refresh_btn = self.find_by_xpath(xpath_for_refresh_btn)
refresh_btn.click()
time.sleep(.5)
# get the expansion status
function_expansion_ele = self.find_by_xpath(xpath_for_exp)
# look into the attribute and check if it is already expanded or
# not
if function_expansion_ele.get_attribute('aria-expanded') \
== 'false':
# button element of the Function node to open it
item_button = self.find_by_xpath(xpath_for_button)
ActionChains(self.driver).click(item_button).perform()
# Expansion of element on GUI takes sometime, so put small
# sleep
time.sleep(.5)
function_expansion_ele = self.find_by_xpath(
xpath_for_exp)
if function_expansion_ele.get_attribute('aria-expanded') \
== 'true':
break
else:
attempts -= 1
else:
node_expanded = True
def toggle_open_server(self, tree_item_text):
def check_for_password_dialog_or_tree_open(driver):
try:
dialog = driver.find_element_by_id("frmPassword")
except WebDriverException:
dialog = None
try:
database_node = driver.find_element_by_xpath(
"//*[@id='tree']//*[.='Databases']"
@ -284,8 +350,15 @@ class PgadminPage:
def fill_input(self, field, field_content, input_keys=False,
key_after_input=Keys.ARROW_DOWN):
field.click()
try:
attempt = 0
for attempt in range(0, 3):
field.click()
break
except Exception as e:
time.sleep(.2)
if attempt == 2:
raise Exception(e)
# Use send keys if input_keys true, else use javascript to set content
if input_keys:
backspaces = [Keys.BACKSPACE] * len(field.get_attribute('value'))

View File

@ -10,14 +10,15 @@
def close_bgprocess_popup(tester):
"""
Allow us to close the background process popup window
Allows us to close the background process popup window
"""
tester._screenshot()
screen_shot_taken = False
# In cases where backup div is not closed (sometime due to some error)
try:
if tester.driver.find_element_by_css_selector(
".ajs-message.ajs-bg-bgprocess.ajs-visible"):
tester._screenshot()
screen_shot_taken = True
tester.driver.find_element_by_css_selector(
".btn.btn-sm-sq.btn-primary.pg-bg-close > i").click()
except Exception:
@ -28,6 +29,8 @@ def close_bgprocess_popup(tester):
if tester.driver.find_element_by_xpath(
"//div[@class='card-header bg-primary d-flex']/div"
"[contains(text(), 'Restoring backup')]"):
tester._screenshot()
screen_shot_taken = True
tester.driver.find_element_by_css_selector(
".btn.btn-sm-sq.btn-primary.pg-bg-close > i").click()
except Exception:
@ -39,7 +42,12 @@ def close_bgprocess_popup(tester):
if tester.driver.find_element_by_xpath(
"//div[@class='card-header bg-primary d-flex']/div"
"[contains(text(), 'Maintenance')]"):
tester._screenshot()
screen_shot_taken = True
tester.driver.find_element_by_css_selector(
".btn.btn-sm-sq.btn-primary.pg-bg-close > i").click()
except Exception:
pass
if not screen_shot_taken:
tester._screenshot()

View File

@ -319,6 +319,26 @@ def drop_debug_function(server, db_name, function_name="test_func"):
traceback.print_exc(file=sys.stderr)
def does_function_exist(server, db_name, fun_name):
query = "select exists(select * " \
"from pg_proc where proname = '%s');" % fun_name
connection = get_db_connection(
db_name,
server['username'],
server['db_password'],
server['host'],
server['port'],
server['sslmode']
)
cursor = connection.cursor()
cursor.execute(query)
result = cursor.fetchall()
return str(result[0][0])
def create_role(server, db_name, role_name="test_role"):
try:
connection = get_db_connection(
@ -1006,3 +1026,22 @@ def check_binary_path_or_skip_test(cls, utility_name):
retVal = is_utility_exists(binary_path)
if retVal is not None:
cls.skipTest(retVal)
def get_watcher_dialogue_status(self):
"""This will get watcher dialogue status"""
import time
attempts = 120
while attempts > 0:
status = self.page.find_by_css_selector(
".pg-bg-status-text").text
if 'Failed' in status:
break
if status == 'Started' or status == 'Running...':
attempts -= 1
time.sleep(.5)
else:
break
return status