Further code refactoring to stabilise the Feature Tests. Fixes #3936

This commit is contained in:
Shubham Agarwal 2019-08-28 18:04:08 +05:30 committed by Akshay Joshi
parent 028473eb83
commit fc4bef56a0
15 changed files with 113 additions and 125 deletions

View File

@ -25,6 +25,7 @@ Bug fixes
| `Issue #2706 <https://redmine.postgresql.org/issues/2706>`_ - Added ProjectSet icon for explain module. | `Issue #2706 <https://redmine.postgresql.org/issues/2706>`_ - Added ProjectSet icon for explain module.
| `Issue #2828 <https://redmine.postgresql.org/issues/2828>`_ - Added Gather Merge, Named Tuple Store Scan and Table Function Scan icon for explain module. | `Issue #2828 <https://redmine.postgresql.org/issues/2828>`_ - Added Gather Merge, Named Tuple Store Scan and Table Function Scan icon for explain module.
| `Issue #3778 <https://redmine.postgresql.org/issues/3778>`_ - Ensure Boolean columns should be editable using keyboard keys. | `Issue #3778 <https://redmine.postgresql.org/issues/3778>`_ - Ensure Boolean columns should be editable using keyboard keys.
| `Issue #3936 <https://redmine.postgresql.org/issues/3936>`_ - Further code refactoring to stabilise the Feature Tests.
| `Issue #4381 <https://redmine.postgresql.org/issues/4381>`_ - Fix an issue where oid column should not be pasted when copy/paste row is used on query output containing the oid column. | `Issue #4381 <https://redmine.postgresql.org/issues/4381>`_ - Fix an issue where oid column should not be pasted when copy/paste row is used on query output containing the oid column.
| `Issue #4419 <https://redmine.postgresql.org/issues/4419>`_ - Fix a debugger error when using Python 2.7. | `Issue #4419 <https://redmine.postgresql.org/issues/4419>`_ - Fix a debugger error when using Python 2.7.
| `Issue #4486 <https://redmine.postgresql.org/issues/4486>`_ - Ensure View should be created with special characters. | `Issue #4486 <https://redmine.postgresql.org/issues/4486>`_ - Ensure View should be created with special characters.

View File

@ -10,11 +10,11 @@
from __future__ import print_function from __future__ import print_function
import sys import sys
import random import random
from regression.python_test_utils import test_utils from regression.python_test_utils import test_utils
from regression.feature_utils.locators import BrowserToolBarLocators from regression.feature_utils.locators import BrowserToolBarLocators
from regression.feature_utils.base_feature_test import BaseFeatureTest from regression.feature_utils.base_feature_test import BaseFeatureTest
from selenium.common.exceptions import TimeoutException, \ from selenium.webdriver.common.by import By
StaleElementReferenceException
class BrowserToolBarFeatureTest(BaseFeatureTest): class BrowserToolBarFeatureTest(BaseFeatureTest):
@ -63,18 +63,10 @@ class BrowserToolBarFeatureTest(BaseFeatureTest):
self.page.toggle_open_tree_item(self.server['name']) self.page.toggle_open_tree_item(self.server['name'])
self.page.toggle_open_tree_item('Databases') self.page.toggle_open_tree_item('Databases')
self.page.toggle_open_tree_item(self.test_db) self.page.toggle_open_tree_item(self.test_db)
retry_count = 0 self.page.retry_click(
while retry_count < 5: (By.CSS_SELECTOR,
try: BrowserToolBarLocators.open_query_tool_button_css),
self.page.find_by_css_selector( (By.CSS_SELECTOR, BrowserToolBarLocators.query_tool_panel_css))
BrowserToolBarLocators.open_query_tool_button_css)\
.click()
break
except (StaleElementReferenceException, TimeoutException):
retry_count += 1
self.page.find_by_css_selector(
BrowserToolBarLocators.query_tool_panel_css)
def test_view_data_tool_button(self): def test_view_data_tool_button(self):
self.page.select_tree_item(self.test_db) self.page.select_tree_item(self.test_db)
@ -83,27 +75,14 @@ class BrowserToolBarFeatureTest(BaseFeatureTest):
self.page.toggle_open_tables_node() self.page.toggle_open_tables_node()
self.page.select_tree_item(self.test_table_name) self.page.select_tree_item(self.test_table_name)
retry_count = 0 self.page.retry_click(
while retry_count < 5: (By.CSS_SELECTOR,
try: BrowserToolBarLocators.view_table_data_button_css),
self.page.find_by_css_selector( (By.CSS_SELECTOR, BrowserToolBarLocators.view_data_panel_css))
BrowserToolBarLocators.view_table_data_button_css).click()
break
except (StaleElementReferenceException, TimeoutException):
retry_count += 1
self.page.find_by_css_selector(
BrowserToolBarLocators.view_data_panel_css)
def test_filtered_rows_tool_button(self): def test_filtered_rows_tool_button(self):
retry_count = 0 self.page.retry_click(
while retry_count < 5: (By.CSS_SELECTOR,
try: BrowserToolBarLocators.filter_data_button_css),
self.page.find_by_css_selector( (By.CSS_SELECTOR, BrowserToolBarLocators.filter_alertify_box_css))
BrowserToolBarLocators.filter_data_button_css)\
.click()
break
except (StaleElementReferenceException, TimeoutException):
retry_count += 1
self.page.find_by_css_selector(
BrowserToolBarLocators.filter_alertify_box_css)
self.page.click_modal('Cancel') self.page.click_modal('Cancel')

View File

@ -7,8 +7,10 @@
# #
########################################################################## ##########################################################################
from __future__ import print_function
import pyperclip import pyperclip
import random import random
from selenium.webdriver import ActionChains from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.keys import Keys
from regression.python_test_utils import test_utils from regression.python_test_utils import test_utils

View File

@ -11,12 +11,12 @@ from __future__ import print_function
import os import os
import sys import sys
import time 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
from selenium.common.exceptions import StaleElementReferenceException, \ from selenium.common.exceptions import StaleElementReferenceException, \
TimeoutException TimeoutException
from selenium.webdriver.support import expected_conditions as EC
from regression.feature_utils.base_feature_test import BaseFeatureTest from regression.feature_utils.base_feature_test import BaseFeatureTest
from regression.feature_utils.locators import QueryToolLocators from regression.feature_utils.locators import QueryToolLocators
@ -126,21 +126,11 @@ class CheckFileManagerFeatureTest(BaseFeatureTest):
# Intermittently facing issue on first click it is not successful # Intermittently facing issue on first click it is not successful
# so tried couple of times. # so tried couple of times.
iteration = 0 success = self.page.retry_click(
success = False (By.XPATH,
while not success and iteration < 4: "//th[@data-column='0']/div/span[text()='Name']"),
# Check for sort Ascending (By.CSS_SELECTOR,
try: "#contents th[data-column='0'].tablesorter-headerAsc"))
self.page.find_by_xpath("//th[@data-column='0']"
"/div/span[text()='Name']").click()
self.wait.until(
EC.presence_of_element_located((
By.CSS_SELECTOR,
"#contents th[data-column='0'].tablesorter-headerAsc")
))
success = True
except Exception as e:
iteration += 1
if not success: if not success:
raise Exception("Unable to sort in ascending order while clicked " raise Exception("Unable to sort in ascending order while clicked "
@ -151,21 +141,11 @@ class CheckFileManagerFeatureTest(BaseFeatureTest):
# Click and Check for sort Descending # Click and Check for sort Descending
# Intermittently facing issue on first click it is not successful # Intermittently facing issue on first click it is not successful
# so tried couple of times. # so tried couple of times.
iteration = 0 success = self.page.retry_click(
success = False (By.XPATH,
while not success and iteration < 4: "//th[@data-column='0']/div/span[text()='Name']"),
(By.CSS_SELECTOR,
try: "#contents th[data-column='0'].tablesorter-headerDesc"))
self.page.find_by_xpath("//th[@data-column='0']"
"/div/span[text()='Name']").click()
self.wait.until(
EC.presence_of_element_located((
By.CSS_SELECTOR,
"#contents th[data-column='0'].tablesorter-headerDesc")
))
success = True
except Exception as e:
iteration += 1
if not success: if not success:
raise Exception("Unable to sort in descending order while clicked " raise Exception("Unable to sort in descending order while clicked "

View File

@ -7,6 +7,7 @@
# #
########################################################################## ##########################################################################
from __future__ import print_function
import os import os
import json import json
import time import time

View File

@ -6,12 +6,13 @@
# This software is released under the PostgreSQL Licence # This software is released under the PostgreSQL Licence
# #
########################################################################## ##########################################################################
from __future__ import print_function
import os import os
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
from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import ElementClickInterceptedException
from regression.feature_utils.base_feature_test import BaseFeatureTest from regression.feature_utils.base_feature_test import BaseFeatureTest
from regression.python_test_utils import test_utils from regression.python_test_utils import test_utils
from regression.python_test_utils import test_gui_helper from regression.python_test_utils import test_gui_helper
@ -39,6 +40,11 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
self.server['name'] self.server['name']
) )
) )
if '<' in self.database_name and os.name == 'nt':
self.skipTest(
"HTML tags '<' and '>' in object name does not "
"work for windows so skipping the test case"
)
connection = test_utils.get_db_connection( connection = test_utils.get_db_connection(
self.server['db'], self.server['db'],
@ -63,14 +69,11 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
self.page.toggle_open_tree_item(self.database_name) self.page.toggle_open_tree_item(self.database_name)
# Backup # Backup
retry = 3 self.page.retry_click(
while retry > 0: (By.LINK_TEXT,
try: NavMenuLocators.tools_menu_link_text),
self.driver.find_element_by_link_text( (By.CSS_SELECTOR,
NavMenuLocators.tools_menu_link_text).click() NavMenuLocators.backup_obj_css))
break
except ElementClickInterceptedException:
retry -= 1
backup_object = self.wait.until(EC.visibility_of_element_located( backup_object = self.wait.until(EC.visibility_of_element_located(
(By.CSS_SELECTOR, NavMenuLocators.backup_obj_css))) (By.CSS_SELECTOR, NavMenuLocators.backup_obj_css)))

View File

@ -6,15 +6,18 @@
# This software is released under the PostgreSQL Licence # This software is released under the PostgreSQL Licence
# #
########################################################################## ##########################################################################
from __future__ import print_function
import random
import os
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By
from selenium.common.exceptions import ElementClickInterceptedException
from regression.feature_utils.base_feature_test import BaseFeatureTest from regression.feature_utils.base_feature_test import BaseFeatureTest
from regression.python_test_utils import test_utils from regression.python_test_utils import test_utils
from regression.python_test_utils import test_gui_helper from regression.python_test_utils import test_gui_helper
from regression.feature_utils.locators import NavMenuLocators from regression.feature_utils.locators import NavMenuLocators
import random
class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest): class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
@ -48,6 +51,11 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
self.server['name'] self.server['name']
) )
) )
if '<' in self.table_name and os.name == 'nt':
self.skipTest(
"HTML tags '<' and '>' in object name does not "
"work for windows so skipping the test case"
)
connection = test_utils.get_db_connection( connection = test_utils.get_db_connection(
self.server['db'], self.server['db'],
@ -90,15 +98,12 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
self.page.toggle_open_tree_item('public') self.page.toggle_open_tree_item('public')
self.page.toggle_open_tables_node() self.page.toggle_open_tables_node()
self.page.select_tree_item(self.table_name) self.page.select_tree_item(self.table_name)
retry = 3
while retry > 0: self.page.retry_click(
try: (By.LINK_TEXT,
tools_menu = self.driver.find_element_by_link_text( NavMenuLocators.tools_menu_link_text),
NavMenuLocators.tools_menu_link_text) (By.CSS_SELECTOR, NavMenuLocators.maintenance_obj_css))
tools_menu.click()
break
except ElementClickInterceptedException:
retry -= 1
maintenance_obj = self.wait.until(EC.visibility_of_element_located( maintenance_obj = self.wait.until(EC.visibility_of_element_located(
(By.CSS_SELECTOR, NavMenuLocators.maintenance_obj_css))) (By.CSS_SELECTOR, NavMenuLocators.maintenance_obj_css)))
maintenance_obj.click() maintenance_obj.click()

View File

@ -308,9 +308,7 @@ class QueryToolJourneyTest(BaseFeatureTest):
query_options = self.page.find_by_css_selector( query_options = self.page.find_by_css_selector(
QueryToolLocators.btn_query_dropdown) QueryToolLocators.btn_query_dropdown)
query_options.click() query_options.click()
self.page.find_by_css_selector( self.page.uncheck_execute_option("auto_commit")
QueryToolLocators.btn_auto_commit).click()
query_options.click() # Click again to close dropdown
self._update_numeric_cell(2, 10) self._update_numeric_cell(2, 10)
@ -320,9 +318,7 @@ class QueryToolJourneyTest(BaseFeatureTest):
query_options = self.page.find_by_css_selector( query_options = self.page.find_by_css_selector(
QueryToolLocators.btn_query_dropdown) QueryToolLocators.btn_query_dropdown)
query_options.click() query_options.click()
self.page.find_by_css_selector( self.page.check_execute_option("auto_commit")
QueryToolLocators.btn_auto_commit).click()
query_options.click() # Click again to close dropdown
def _check_history_queries_and_icons(self, history_queries, history_icons): def _check_history_queries_and_icons(self, history_queries, history_icons):
# Select first query history entry # Select first query history entry
@ -422,9 +418,6 @@ class QueryToolJourneyTest(BaseFeatureTest):
def _check_cell_editable(self, cell_index): def _check_cell_editable(self, cell_index):
"""Checks if a cell in the first row of the resultset is editable""" """Checks if a cell in the first row of the resultset is editable"""
# self.page.check_if_element_exist_by_xpath(
# "//div[contains(@style, 'top:0px')]//div[contains(@class, "
# "'l{0} r{1}')]".format(cell_index, cell_index))
cell_el = self.page.find_by_xpath( cell_el = self.page.find_by_xpath(
"//div[contains(@style, 'top:0px')]//div[contains(@class, " "//div[contains(@style, 'top:0px')]//div[contains(@class, "
"'l{0} r{1}')]".format(cell_index, cell_index)) "'l{0} r{1}')]".format(cell_index, cell_index))

View File

@ -9,6 +9,7 @@
from __future__ import print_function from __future__ import print_function
import sys import sys
import time
from selenium.common.exceptions import StaleElementReferenceException, \ from selenium.common.exceptions import StaleElementReferenceException, \
ElementClickInterceptedException ElementClickInterceptedException
@ -242,7 +243,6 @@ SELECT generate_series(1, {}) as id1, 'dummy' as id2""".format(
def _check_ondemand_result(self, row_id_to_find): def _check_ondemand_result(self, row_id_to_find):
# scroll to bottom to bring last row of next chunk in viewport. # scroll to bottom to bring last row of next chunk in viewport.
# canvas_ele = self.page.find_by_css_selector()
scroll = 10 scroll = 10
while scroll: while scroll:
canvas_ele = self.page.find_by_css_selector('.grid-canvas') canvas_ele = self.page.find_by_css_selector('.grid-canvas')
@ -252,8 +252,9 @@ SELECT generate_series(1, {}) as id1, 'dummy' as id2""".format(
".scrollTop(pgAdmin.SqlEditor.jquery('.grid-canvas')" ".scrollTop(pgAdmin.SqlEditor.jquery('.grid-canvas')"
".height());" ".height());"
) )
import time # Table height takes some time to update, for which their is no
time.sleep(0.5) # particular way
time.sleep(1)
if canvas_ele.size['height'] == scrolling_height: if canvas_ele.size['height'] == scrolling_height:
break break
else: else:

View File

@ -7,6 +7,7 @@
# #
########################################################################## ##########################################################################
from __future__ import print_function
import random import random
from regression.feature_utils.base_feature_test import BaseFeatureTest from regression.feature_utils.base_feature_test import BaseFeatureTest

View File

@ -7,6 +7,7 @@
# #
########################################################################## ##########################################################################
from __future__ import print_function
import json import json
import os import os
import time import time

View File

@ -10,6 +10,7 @@
from __future__ import print_function from __future__ import print_function
import sys import sys
import random import random
from regression.python_test_utils import test_utils from regression.python_test_utils import test_utils
from regression.feature_utils.base_feature_test import BaseFeatureTest from regression.feature_utils.base_feature_test import BaseFeatureTest
from selenium.webdriver import ActionChains from selenium.webdriver import ActionChains

View File

@ -7,6 +7,7 @@
# #
########################################################################## ##########################################################################
from __future__ import print_function
import random import random
from selenium.webdriver import ActionChains from selenium.webdriver import ActionChains

View File

@ -6,6 +6,8 @@
# This software is released under the PostgreSQL Licence # This software is released under the PostgreSQL Licence
# #
########################################################################## ##########################################################################
from __future__ import print_function
import random import random
from regression.python_test_utils import test_utils from regression.python_test_utils import test_utils
@ -89,16 +91,8 @@ class CheckRoleMembershipControlFeatureTest(BaseFeatureTest):
def click_membership_tab(self): def click_membership_tab(self):
"""This will click and open membership tab of role""" """This will click and open membership tab of role"""
success = False
attempts = 3 self.page.retry_click(
while not success and attempts > 0: (By.XPATH,
membership_tab_link = self.page.find_by_xpath( "//a[normalize-space(text())='Membership']"),
"//a[normalize-space(text())='Membership']") (By.XPATH, "//input[@placeholder='Select members']"))
membership_tab_link.click()
try:
self.page.find_by_xpath("//input[@placeholder="
"'Select members']")
break
except Exception as e:
attempts -= 1
pass

View File

@ -175,6 +175,38 @@ class PgadminPage:
execute_button.click() execute_button.click()
self.wait_for_query_tool_loading_indicator_to_disappear() 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"""
if option == 'auto_commit':
check_status = self.driver.find_element_by_css_selector(
QueryToolLocators.btn_auto_commit_check_status)
if 'visibility-hidden' in check_status.get_attribute('class'):
self.find_by_css_selector(
QueryToolLocators.btn_auto_commit).click()
if option == 'auto_rollback':
check_status = self.driver.find_element_by_css_selector(
QueryToolLocators.btn_auto_rollback_check_status)
if 'visibility-hidden' in check_status.get_attribute('class'):
self.find_by_css_selector(
QueryToolLocators.btn_auto_rollback).click()
def uncheck_execute_option(self, option):
""""This function will uncheck auto commit or auto roll back based on
user input. If button is already unchecked, no action will be taken"""
if option == 'auto_commit':
check_status = self.driver.find_element_by_css_selector(
QueryToolLocators.btn_auto_commit_check_status)
if 'visibility-hidden' not in check_status.get_attribute('class'):
self.find_by_css_selector(
QueryToolLocators.btn_auto_commit).click()
if option == 'auto_rollback':
check_status = self.driver.find_element_by_css_selector(
QueryToolLocators.btn_auto_rollback_check_status)
if 'visibility-hidden' not in check_status.get_attribute('class'):
self.find_by_css_selector(
QueryToolLocators.btn_auto_rollback).click()
def close_data_grid(self): def close_data_grid(self):
self.driver.switch_to_default_content() self.driver.switch_to_default_content()
xpath = "//*[@id='dockerContainer']/div/div[3]/div/div[2]/div[1]" xpath = "//*[@id='dockerContainer']/div/div[3]/div/div[2]/div[1]"
@ -712,24 +744,17 @@ class PgadminPage:
status_changed_successfully = True status_changed_successfully = True
return status_changed_successfully return status_changed_successfully
def retry_click_operation(self, element_to_click, def retry_click(self, click_locator, verify_locator):
element_to_verify_after_click):
"""This will attempt to click add button multiple time,
some different exception encountered while clicking, so handled
through this"""
click_status = False click_status = False
attempt = 0 attempt = 0
while click_status is not True and attempt < 5: while click_status is not True and attempt < 5:
try: try:
if element_to_verify_after_click.is_displayed(): element = self.driver.find_element(*click_locator)
click_status = True element.click()
element_to_click.click() WebDriverWait(self.driver, 5).until(
if element_to_verify_after_click.is_displayed(): EC.visibility_of_element_located(verify_locator))
click_status = True click_status = True
except Exception: except Exception:
print("The click operation is not performed for " attempt = +1
"attempt %s, will try 5 attempts" % attempt)
attempt = +1
return click_status return click_status