Cleanup feature tests. Fixes #2586
parent
401e13ca65
commit
ceb9438000
|
@ -1,84 +0,0 @@
|
|||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2017, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
import time
|
||||
from selenium.webdriver import ActionChains
|
||||
|
||||
import config as app_config
|
||||
from regression.feature_utils.base_feature_test import BaseFeatureTest
|
||||
from regression.python_test_utils import test_utils
|
||||
|
||||
|
||||
class ConnectsToServerFeatureTest(BaseFeatureTest):
|
||||
"""
|
||||
Tests that a database connection can be created from the UI
|
||||
"""
|
||||
scenarios = [
|
||||
("Test database connection", dict())
|
||||
]
|
||||
|
||||
def before(self):
|
||||
connection = test_utils.get_db_connection(self.server['db'],
|
||||
self.server['username'],
|
||||
self.server['db_password'],
|
||||
self.server['host'],
|
||||
self.server['port'],
|
||||
self.server['sslmode'])
|
||||
test_utils.drop_database(connection, "acceptance_test_db")
|
||||
test_utils.create_database(self.server, "acceptance_test_db")
|
||||
test_utils.create_table(self.server, "acceptance_test_db", "test_table")
|
||||
|
||||
def runTest(self):
|
||||
"""This function tests that a database connection can be created from
|
||||
the UI"""
|
||||
self.assertEqual(app_config.APP_NAME, self.page.driver.title)
|
||||
self.page.wait_for_spinner_to_disappear()
|
||||
|
||||
self._connects_to_server()
|
||||
self._tables_node_expandable()
|
||||
|
||||
def after(self):
|
||||
self.page.remove_server(self.server)
|
||||
|
||||
connection = test_utils.get_db_connection(self.server['db'],
|
||||
self.server['username'],
|
||||
self.server['db_password'],
|
||||
self.server['host'],
|
||||
self.server['port'],
|
||||
self.server['sslmode'])
|
||||
test_utils.drop_database(connection, "acceptance_test_db")
|
||||
|
||||
def _connects_to_server(self):
|
||||
self.page.find_by_xpath("//*[@class='aciTreeText' and .='Servers']").click()
|
||||
time.sleep(2)
|
||||
self.page.driver.find_element_by_link_text("Object").click()
|
||||
ActionChains(self.page.driver) \
|
||||
.move_to_element(self.page.driver.find_element_by_link_text("Create")) \
|
||||
.perform()
|
||||
self.page.find_by_partial_link_text("Server...").click()
|
||||
|
||||
server_config = self.server
|
||||
self.page.fill_input_by_field_name("name", server_config['name'])
|
||||
self.page.find_by_partial_link_text("Connection").click()
|
||||
self.page.fill_input_by_field_name("host", server_config['host'])
|
||||
self.page.fill_input_by_field_name("port", server_config['port'])
|
||||
self.page.fill_input_by_field_name("username", server_config['username'])
|
||||
self.page.fill_input_by_field_name("password", server_config['db_password'])
|
||||
self.page.find_by_xpath("//button[contains(.,'Save')]").click()
|
||||
|
||||
def _tables_node_expandable(self):
|
||||
self.page.toggle_open_server(self.server['name'])
|
||||
self.page.toggle_open_tree_item('Databases')
|
||||
self.page.toggle_open_tree_item('acceptance_test_db')
|
||||
# wait until all database dependant modules/js are loaded.
|
||||
time.sleep(5)
|
||||
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_tree_item('test_table')
|
|
@ -8,7 +8,6 @@
|
|||
##########################################################################
|
||||
|
||||
import pyperclip
|
||||
import time
|
||||
|
||||
from selenium.webdriver import ActionChains
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
|
@ -42,16 +41,16 @@ class CopySelectedQueryResultsFeatureTest(BaseFeatureTest):
|
|||
self.page.toggle_open_tree_item(self.server['name'])
|
||||
self.page.toggle_open_tree_item('Databases')
|
||||
self.page.toggle_open_tree_item('acceptance_test_db')
|
||||
time.sleep(5)
|
||||
self.page.find_by_partial_link_text("Tools").click()
|
||||
self.page.find_by_partial_link_text("Query Tool").click()
|
||||
self.page.click_tab('Query -')
|
||||
time.sleep(5)
|
||||
ActionChains(self.page.driver).send_keys("SELECT * FROM test_table ORDER BY some_column").perform()
|
||||
self.page.driver.switch_to_frame(self.page.driver.find_element_by_tag_name("iframe"))
|
||||
self.page.open_query_tool()
|
||||
|
||||
self.page.driver.switch_to_frame(
|
||||
self.page.driver.find_element_by_tag_name("iframe"))
|
||||
|
||||
self.page.fill_codemirror_area_with(
|
||||
"SELECT * FROM test_table ORDER BY some_column")
|
||||
|
||||
self.page.find_by_id("btn-flash").click()
|
||||
|
||||
time.sleep(5)
|
||||
self._copies_rows()
|
||||
self._copies_columns()
|
||||
self._copies_row_using_keyboard_shortcut()
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
import time
|
||||
from selenium.webdriver import ActionChains
|
||||
|
||||
from selenium.common.exceptions import TimeoutException
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
|
@ -38,7 +37,7 @@ class PGDataypeFeatureTest(BaseFeatureTest):
|
|||
|
||||
def runTest(self):
|
||||
self.page.wait_for_spinner_to_disappear()
|
||||
self._connects_to_server()
|
||||
self.page.add_server(self.server)
|
||||
self._schema_node_expandable()
|
||||
|
||||
# Check data types
|
||||
|
@ -55,31 +54,6 @@ class PGDataypeFeatureTest(BaseFeatureTest):
|
|||
self.server['sslmode'])
|
||||
test_utils.drop_database(connection, "acceptance_test_db")
|
||||
|
||||
def _connects_to_server(self):
|
||||
self.page.find_by_xpath(
|
||||
"//*[@class='aciTreeText' and .='Servers']"
|
||||
).click()
|
||||
time.sleep(2)
|
||||
self.page.driver.find_element_by_link_text("Object").click()
|
||||
ActionChains(self.page.driver) \
|
||||
.move_to_element(
|
||||
self.page.driver.find_element_by_link_text("Create")
|
||||
).perform()
|
||||
self.page.find_by_partial_link_text("Server...").click()
|
||||
|
||||
server_config = self.server
|
||||
self.page.fill_input_by_field_name("name", server_config['name'])
|
||||
self.page.find_by_partial_link_text("Connection").click()
|
||||
self.page.fill_input_by_field_name("host", server_config['host'])
|
||||
self.page.fill_input_by_field_name("port", server_config['port'])
|
||||
self.page.fill_input_by_field_name(
|
||||
"username", server_config['username']
|
||||
)
|
||||
self.page.fill_input_by_field_name(
|
||||
"password", server_config['db_password']
|
||||
)
|
||||
self.page.find_by_xpath("//button[contains(.,'Save')]").click()
|
||||
|
||||
def _schema_node_expandable(self):
|
||||
self.page.toggle_open_tree_item(self.server['name'])
|
||||
self.page.toggle_open_tree_item('Databases')
|
||||
|
@ -136,11 +110,9 @@ class PGDataypeFeatureTest(BaseFeatureTest):
|
|||
|
||||
@staticmethod
|
||||
def check_result(source_code, string_to_find):
|
||||
if source_code.find(string_to_find) == -1:
|
||||
assert False, "{0} does not match with {1}".format(
|
||||
assert source_code.find(string_to_find) != -1,\
|
||||
"{0} does not match with {1}".format(
|
||||
source_code, string_to_find
|
||||
)
|
||||
else:
|
||||
assert True
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
##########################################################################
|
||||
|
||||
import pyperclip
|
||||
import time
|
||||
|
||||
from selenium.webdriver import ActionChains
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
|
@ -39,7 +38,10 @@ class QueryToolJourneyTest(BaseFeatureTest):
|
|||
|
||||
def runTest(self):
|
||||
self._navigate_to_query_tool()
|
||||
self._execute_query("SELECT * FROM test_table ORDER BY value")
|
||||
|
||||
self._execute_query(
|
||||
"SELECT * FROM test_table ORDER BY value"
|
||||
)
|
||||
|
||||
self._test_copies_rows()
|
||||
self._test_copies_columns()
|
||||
|
@ -47,7 +49,6 @@ class QueryToolJourneyTest(BaseFeatureTest):
|
|||
|
||||
def _test_copies_rows(self):
|
||||
pyperclip.copy("old clipboard contents")
|
||||
time.sleep(5)
|
||||
self.page.driver.switch_to.default_content()
|
||||
self.page.driver.switch_to_frame(self.page.driver.find_element_by_tag_name("iframe"))
|
||||
self.page.find_by_xpath("//*[contains(@class, 'slick-row')]/*[1]").click()
|
||||
|
@ -95,8 +96,11 @@ class QueryToolJourneyTest(BaseFeatureTest):
|
|||
self.__clear_query_tool()
|
||||
|
||||
self.page.click_element(editor_input)
|
||||
|
||||
self.page.fill_codemirror_area_with("SELECT * FROM hats")
|
||||
for _ in range(15):
|
||||
self._execute_query("SELECT * FROM hats")
|
||||
self.page.find_by_id("btn-flash").click()
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
|
||||
self.page.click_tab("Query History")
|
||||
|
||||
|
@ -113,8 +117,10 @@ class QueryToolJourneyTest(BaseFeatureTest):
|
|||
|
||||
self.__clear_query_tool()
|
||||
self.page.click_element(editor_input)
|
||||
self.page.fill_codemirror_area_with("SELECT * FROM hats")
|
||||
for _ in range(15):
|
||||
self._execute_query("SELECT * FROM hats")
|
||||
self.page.find_by_id("btn-flash").click()
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
|
||||
self.page.click_tab("History")
|
||||
query_we_need_to_scroll_to = self.page.find_by_xpath(
|
||||
|
@ -143,12 +149,9 @@ class QueryToolJourneyTest(BaseFeatureTest):
|
|||
self.page.toggle_open_tree_item('Databases')
|
||||
self.page.toggle_open_tree_item('acceptance_test_db')
|
||||
self.page.open_query_tool()
|
||||
time.sleep(5)
|
||||
|
||||
def _execute_query(self, query):
|
||||
ActionChains(self.page.driver).send_keys(query).perform()
|
||||
self.page.driver.switch_to.default_content()
|
||||
self.page.driver.switch_to_frame(self.page.driver.find_element_by_tag_name("iframe"))
|
||||
self.page.fill_codemirror_area_with(query)
|
||||
self.page.find_by_id("btn-flash").click()
|
||||
|
||||
def _assert_clickable(self, element):
|
||||
|
|
|
@ -38,68 +38,28 @@ class QueryToolFeatureTest(BaseFeatureTest):
|
|||
test_utils.drop_database(connection, "acceptance_test_db")
|
||||
test_utils.create_database(self.server, "acceptance_test_db")
|
||||
self.page.wait_for_spinner_to_disappear()
|
||||
self._connects_to_server()
|
||||
self.page.add_server(self.server)
|
||||
self._locate_database_tree_node()
|
||||
self.page.open_query_tool()
|
||||
|
||||
def runTest(self):
|
||||
# on demand result set on scrolling.
|
||||
print("\nOn demand result set on scrolling... ",
|
||||
print("\nOn demand query result... ",
|
||||
file=sys.stderr, end="")
|
||||
self._on_demand_result()
|
||||
print("OK.",
|
||||
file=sys.stderr)
|
||||
self._clear_query_tool()
|
||||
|
||||
# on demand result set on grid select all.
|
||||
print("On demand result set on grid select all... ",
|
||||
# explain query with verbose and cost
|
||||
print("Explain query with verbose and cost... ",
|
||||
file=sys.stderr, end="")
|
||||
self._on_demand_result_select_all_grid()
|
||||
print("OK.",
|
||||
file=sys.stderr)
|
||||
self._query_tool_explain_with_verbose_and_cost()
|
||||
print("OK.", file=sys.stderr)
|
||||
self._clear_query_tool()
|
||||
|
||||
# on demand result set on column select all.
|
||||
print("On demand result set on column select all... ",
|
||||
# explain analyze query with buffers and timing
|
||||
print("Explain analyze query with buffers and timing... ",
|
||||
file=sys.stderr, end="")
|
||||
self._on_demand_result_select_all_column()
|
||||
print("OK.",
|
||||
file=sys.stderr)
|
||||
self._clear_query_tool()
|
||||
|
||||
# explain query
|
||||
print("Explain query... ", file=sys.stderr, end="")
|
||||
self._query_tool_explain()
|
||||
print("OK.", file=sys.stderr)
|
||||
self._clear_query_tool()
|
||||
|
||||
# explain query with verbose
|
||||
print("Explain query with verbose... ", file=sys.stderr, end="")
|
||||
self._query_tool_explain_verbose()
|
||||
print("OK.", file=sys.stderr)
|
||||
self._clear_query_tool()
|
||||
|
||||
# explain query with costs
|
||||
print("Explain query with costs... ", file=sys.stderr, end="")
|
||||
self._query_tool_explain_cost()
|
||||
print("OK.", file=sys.stderr)
|
||||
self._clear_query_tool()
|
||||
|
||||
# explain analyze query
|
||||
print("Explain analyze query... ", file=sys.stderr, end="")
|
||||
self._query_tool_explain_analyze()
|
||||
print("OK.", file=sys.stderr)
|
||||
self._clear_query_tool()
|
||||
|
||||
# explain analyze query with buffers
|
||||
print("Explain analyze query with buffers... ", file=sys.stderr, end="")
|
||||
self._query_tool_explain_analyze_buffers()
|
||||
print("OK.", file=sys.stderr)
|
||||
self._clear_query_tool()
|
||||
|
||||
# explain analyze query with timing
|
||||
print("Explain analyze query with timing... ", file=sys.stderr, end="")
|
||||
self._query_tool_explain_analyze_timing()
|
||||
self._query_tool_explain_analyze_with_buffers_and_timing()
|
||||
print("OK.", file=sys.stderr)
|
||||
self._clear_query_tool()
|
||||
|
||||
|
@ -137,32 +97,6 @@ class QueryToolFeatureTest(BaseFeatureTest):
|
|||
self.server['sslmode'])
|
||||
test_utils.drop_database(connection, "acceptance_test_db")
|
||||
|
||||
def _connects_to_server(self):
|
||||
self.page.find_by_xpath(
|
||||
"//*[@class='aciTreeText' and .='Servers']").click()
|
||||
time.sleep(2)
|
||||
self.page.driver.find_element_by_link_text("Object").click()
|
||||
ActionChains(self.page.driver) \
|
||||
.move_to_element(
|
||||
self.page.driver.find_element_by_link_text("Create"))\
|
||||
.perform()
|
||||
self.page.find_by_partial_link_text("Server...").click()
|
||||
|
||||
server_config = self.server
|
||||
self.page.fill_input_by_field_name("name", server_config['name'])
|
||||
self.page.find_by_partial_link_text("Connection").click()
|
||||
self.page.fill_input_by_field_name("host", server_config['host'])
|
||||
self.page.fill_input_by_field_name("port", server_config['port'])
|
||||
self.page.fill_input_by_field_name(
|
||||
"username",
|
||||
server_config['username']
|
||||
)
|
||||
self.page.fill_input_by_field_name(
|
||||
"password",
|
||||
server_config['db_password']
|
||||
)
|
||||
self.page.find_by_xpath("//button[contains(.,'Save')]").click()
|
||||
|
||||
def _locate_database_tree_node(self):
|
||||
self.page.toggle_open_tree_item(self.server['name'])
|
||||
self.page.toggle_open_tree_item('Databases')
|
||||
|
@ -182,169 +116,105 @@ class QueryToolFeatureTest(BaseFeatureTest):
|
|||
|
||||
def _on_demand_result(self):
|
||||
ON_DEMAND_CHUNKS = 2
|
||||
query = """-- On demand query result on scroll
|
||||
SELECT generate_series(1, {}) as id""".format(
|
||||
row_id_to_find = config.ON_DEMAND_RECORD_COUNT * ON_DEMAND_CHUNKS
|
||||
|
||||
query = """-- On demand query result on scroll, grid select all, column select all
|
||||
SELECT generate_series(1, {}) as id1, 'dummy' as id2""".format(
|
||||
config.ON_DEMAND_RECORD_COUNT * ON_DEMAND_CHUNKS)
|
||||
|
||||
print("\nOn demand result set on scrolling... ",
|
||||
file=sys.stderr, end="")
|
||||
wait = WebDriverWait(self.page.driver, 10)
|
||||
time.sleep(1)
|
||||
self.page.fill_codemirror_area_with(query)
|
||||
|
||||
self.page.find_by_id("btn-flash").click()
|
||||
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
# self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
|
||||
canvas = wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, "#datagrid .slick-viewport .grid-canvas")))
|
||||
wait.until(EC.presence_of_element_located(
|
||||
(By.XPATH,
|
||||
'//span[@data-row="0" and text()="1"]'))
|
||||
)
|
||||
|
||||
# scroll to bottom to fetch next chunk of result set.
|
||||
self.driver.execute_script(
|
||||
"pgAdmin.SqlEditor.jquery('.slick-viewport').scrollTop(pgAdmin.SqlEditor.jquery('.grid-canvas').height());"
|
||||
)
|
||||
# wait for ajax to complete.
|
||||
time.sleep(1)
|
||||
|
||||
# again scroll to bottom to bring last row of next chunk in
|
||||
# viewport.
|
||||
self.driver.execute_script(
|
||||
"pgAdmin.SqlEditor.jquery('.slick-viewport').scrollTop(pgAdmin.SqlEditor.jquery('.grid-canvas').height());"
|
||||
)
|
||||
canvas = wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, "#datagrid .slick-viewport .grid-canvas")))
|
||||
|
||||
row_id_to_find = config.ON_DEMAND_RECORD_COUNT * ON_DEMAND_CHUNKS
|
||||
|
||||
canvas.find_element_by_xpath(
|
||||
'//span[text()="{}"]'.format(row_id_to_find)
|
||||
)
|
||||
|
||||
def _on_demand_result_select_all_grid(self):
|
||||
ON_DEMAND_CHUNKS = 3
|
||||
query = """-- On demand query result on grid select all
|
||||
SELECT generate_series(1, {}) as id""".format(
|
||||
config.ON_DEMAND_RECORD_COUNT * ON_DEMAND_CHUNKS)
|
||||
|
||||
wait = WebDriverWait(self.page.driver, 10)
|
||||
|
||||
self.page.fill_codemirror_area_with(query)
|
||||
self._check_ondemand_result(row_id_to_find, canvas)
|
||||
print("OK.", file=sys.stderr)
|
||||
|
||||
print("On demand result set on grid select all... ",
|
||||
file=sys.stderr, end="")
|
||||
self.page.find_by_id("btn-flash").click()
|
||||
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
# self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
|
||||
wait.until(EC.presence_of_element_located(
|
||||
(By.XPATH,
|
||||
'//span[@data-row="0" and text()="1"]'))
|
||||
)
|
||||
|
||||
wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, ".slick-header-column"))).click()
|
||||
|
||||
# wait for until all records are fetched and selected.
|
||||
time.sleep(1)
|
||||
# scroll to bottom to bring last row of next chunk in
|
||||
# viewport.
|
||||
self.driver.execute_script(
|
||||
"pgAdmin.SqlEditor.jquery('.slick-viewport').scrollTop(pgAdmin.SqlEditor.jquery('.grid-canvas').height());"
|
||||
)
|
||||
|
||||
canvas = wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, "#datagrid .slick-viewport .grid-canvas"))
|
||||
)
|
||||
(By.CSS_SELECTOR, "#datagrid .slick-viewport .grid-canvas")))
|
||||
|
||||
row_id_to_find = config.ON_DEMAND_RECORD_COUNT * ON_DEMAND_CHUNKS
|
||||
|
||||
canvas.find_element_by_xpath(
|
||||
'//span[text()="{}"]'.format(row_id_to_find)
|
||||
)
|
||||
|
||||
def _on_demand_result_select_all_column(self):
|
||||
ON_DEMAND_CHUNKS = 4
|
||||
query = """-- On demand query result on column select all
|
||||
SELECT generate_series(1, {}) as id1, 'dummy' as id2""".format(
|
||||
config.ON_DEMAND_RECORD_COUNT * ON_DEMAND_CHUNKS)
|
||||
|
||||
wait = WebDriverWait(self.page.driver, 10)
|
||||
|
||||
self.page.fill_codemirror_area_with(query)
|
||||
self._check_ondemand_result(row_id_to_find, canvas)
|
||||
print("OK.", file=sys.stderr)
|
||||
|
||||
print("On demand result set on column select all... ",
|
||||
file=sys.stderr, end="")
|
||||
self.page.find_by_id("btn-flash").click()
|
||||
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
# self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
|
||||
wait.until(EC.presence_of_element_located(
|
||||
(By.XPATH,
|
||||
'//span[@data-row="0" and text()="1"]'))
|
||||
)
|
||||
|
||||
# click on first data column to select all column.
|
||||
|
||||
wait.until(EC.presence_of_element_located(
|
||||
(
|
||||
By.XPATH,
|
||||
"//span[contains(@class, 'column-name') and contains(., 'id1')]"))
|
||||
).click()
|
||||
|
||||
# wait for until all records are fetched and selected.
|
||||
time.sleep(1)
|
||||
# scroll to bottom to bring last row of next chunk in
|
||||
# viewport.
|
||||
canvas = wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, "#datagrid .slick-viewport .grid-canvas")))
|
||||
|
||||
self._check_ondemand_result(row_id_to_find, canvas)
|
||||
print("OK.", file=sys.stderr)
|
||||
|
||||
def _check_ondemand_result(self, row_id_to_find, canvas):
|
||||
# scroll to bottom to bring last row of next chunk in viewport.
|
||||
self.driver.execute_script(
|
||||
"pgAdmin.SqlEditor.jquery('.slick-viewport').scrollTop(pgAdmin.SqlEditor.jquery('.grid-canvas').height());"
|
||||
)
|
||||
|
||||
canvas = wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, "#datagrid .slick-viewport .grid-canvas"))
|
||||
)
|
||||
|
||||
row_id_to_find = config.ON_DEMAND_RECORD_COUNT * ON_DEMAND_CHUNKS
|
||||
|
||||
canvas.find_element_by_xpath(
|
||||
'//span[text()="{}"]'.format(row_id_to_find)
|
||||
)
|
||||
|
||||
def _query_tool_explain(self):
|
||||
query = """-- Explain query
|
||||
def _query_tool_explain_with_verbose_and_cost(self):
|
||||
query = """-- Explain query with verbose and cost
|
||||
SELECT generate_series(1, 1000) as id order by id desc"""
|
||||
|
||||
wait = WebDriverWait(self.page.driver, 10)
|
||||
|
||||
self.page.fill_codemirror_area_with(query)
|
||||
self.page.find_by_id("btn-query-dropdown").click()
|
||||
self.page.find_by_id("btn-explain").click()
|
||||
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
|
||||
self.page.click_tab('Data Output')
|
||||
|
||||
canvas = wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, "#datagrid .slick-viewport .grid-canvas"))
|
||||
)
|
||||
# Search for Plan word in result
|
||||
canvas.find_element_by_xpath("//*[contains(string(),'Plan')]")
|
||||
|
||||
def _query_tool_explain_verbose(self):
|
||||
query = """-- Explain query with verbose
|
||||
SELECT generate_series(1, 1000) as id order by id desc"""
|
||||
|
||||
wait = WebDriverWait(self.page.driver, 10)
|
||||
self.page.fill_codemirror_area_with(query)
|
||||
query_op = self.page.find_by_id("btn-query-dropdown")
|
||||
query_op.click()
|
||||
ActionChains(self.driver).move_to_element(
|
||||
query_op.find_element_by_xpath(
|
||||
"//li[contains(.,'Explain Options')]")).perform()
|
||||
|
||||
self.page.find_by_id("btn-explain-verbose").click()
|
||||
self.page.find_by_id("btn-explain").click()
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
self.page.click_tab('Data Output')
|
||||
canvas = wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, "#datagrid .slick-viewport .grid-canvas"))
|
||||
)
|
||||
# Search for 'Output' word in result
|
||||
canvas.find_element_by_xpath("//*[contains(string(), 'Output')]")
|
||||
|
||||
def _query_tool_explain_cost(self):
|
||||
query = """-- Explain query with costs
|
||||
SELECT generate_series(1, 1000) as id order by id desc"""
|
||||
|
||||
wait = WebDriverWait(self.page.driver, 10)
|
||||
|
||||
self.page.fill_codemirror_area_with(query)
|
||||
query_op = self.page.find_by_id("btn-query-dropdown")
|
||||
query_op.click()
|
||||
|
||||
ActionChains(self.driver).move_to_element(
|
||||
query_op.find_element_by_xpath(
|
||||
"//li[contains(.,'Explain Options')]")).perform()
|
||||
|
||||
self.page.find_by_id("btn-explain-costs").click()
|
||||
|
||||
|
@ -357,32 +227,15 @@ SELECT generate_series(1, 1000) as id order by id desc"""
|
|||
canvas = wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, "#datagrid .slick-viewport .grid-canvas"))
|
||||
)
|
||||
# Search for 'Total Cost word in result
|
||||
|
||||
# Search for 'Output' word in result (verbose option)
|
||||
canvas.find_element_by_xpath("//*[contains(string(), 'Output')]")
|
||||
|
||||
# Search for 'Total Cost' word in result (cost option)
|
||||
canvas.find_element_by_xpath("//*[contains(string(),'Total Cost')]")
|
||||
|
||||
def _query_tool_explain_analyze(self):
|
||||
query = """-- Explain analyze query
|
||||
SELECT generate_series(1, 1000) as id order by id desc"""
|
||||
|
||||
wait = WebDriverWait(self.page.driver, 10)
|
||||
|
||||
self.page.fill_codemirror_area_with(query)
|
||||
|
||||
self.page.find_by_id("btn-query-dropdown").click()
|
||||
self.page.find_by_id("btn-explain-analyze").click()
|
||||
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
|
||||
self.page.click_tab('Data Output')
|
||||
|
||||
canvas = wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, "#datagrid .slick-viewport .grid-canvas"))
|
||||
)
|
||||
# Search for Actual Rows word in result
|
||||
canvas.find_element_by_xpath("//*[contains(string(),'Actual Rows')]")
|
||||
|
||||
def _query_tool_explain_analyze_buffers(self):
|
||||
query = """-- Explain analyze query with buffers
|
||||
def _query_tool_explain_analyze_with_buffers_and_timing(self):
|
||||
query = """-- Explain analyze query with buffers and timing
|
||||
SELECT generate_series(1, 1000) as id order by id desc"""
|
||||
|
||||
wait = WebDriverWait(self.page.driver, 10)
|
||||
|
@ -398,32 +251,6 @@ SELECT generate_series(1, 1000) as id order by id desc"""
|
|||
|
||||
self.page.find_by_id("btn-explain-buffers").click()
|
||||
|
||||
self.page.find_by_id("btn-explain-analyze").click()
|
||||
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
|
||||
self.page.click_tab('Data Output')
|
||||
|
||||
canvas = wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, "#datagrid .slick-viewport .grid-canvas"))
|
||||
)
|
||||
# Search for 'Shared Read Blocks' word in result
|
||||
canvas.find_element_by_xpath("//*[contains(string(), 'Shared Read Blocks')]")
|
||||
|
||||
def _query_tool_explain_analyze_timing(self):
|
||||
query = """-- Explain analyze query with timing
|
||||
SELECT generate_series(1, 1000) as id order by id desc"""
|
||||
|
||||
wait = WebDriverWait(self.page.driver, 10)
|
||||
|
||||
self.page.fill_codemirror_area_with(query)
|
||||
query_op = self.page.find_by_id("btn-query-dropdown")
|
||||
query_op.click()
|
||||
|
||||
ActionChains(self.driver).move_to_element(
|
||||
query_op.find_element_by_xpath(
|
||||
"//li[contains(.,'Explain Options')]")).perform()
|
||||
|
||||
self.page.find_by_id("btn-explain-timing").click()
|
||||
|
||||
self.page.find_by_id("btn-explain-analyze").click()
|
||||
|
@ -435,8 +262,15 @@ SELECT generate_series(1, 1000) as id order by id desc"""
|
|||
canvas = wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, "#datagrid .slick-viewport .grid-canvas"))
|
||||
)
|
||||
# Search for 'Actual Total Time' word in result
|
||||
canvas.find_element_by_xpath("//*[contains(string(), 'Actual Total Time')]")
|
||||
# Search for 'Shared Read Blocks' word in result (buffers option)
|
||||
canvas.find_element_by_xpath(
|
||||
"//*[contains(string(), 'Shared Read Blocks')]"
|
||||
)
|
||||
|
||||
# Search for 'Actual Total Time' word in result (timing option)
|
||||
canvas.find_element_by_xpath(
|
||||
"//*[contains(string(), 'Actual Total Time')]"
|
||||
)
|
||||
|
||||
def _query_tool_auto_commit_disabled(self):
|
||||
table_name = 'query_tool_auto_commit_disabled_table'
|
||||
|
@ -451,23 +285,12 @@ CREATE TABLE public.{}();""".format(table_name)
|
|||
|
||||
self.page.find_by_id("btn-query-dropdown").click()
|
||||
|
||||
auto_commit_btn = self.page.find_by_id("btn-auto-commit")
|
||||
|
||||
auto_commit_check = auto_commit_btn.find_element_by_tag_name("i")
|
||||
|
||||
# if auto commit is enabled then 'i' element will
|
||||
# have 'auto-commit fa fa-check' classes
|
||||
# if auto commit is disabled then 'i' element will
|
||||
# have 'auto-commit fa fa-check visibility-hidden' classes
|
||||
|
||||
if 'auto-commit fa fa-check' == str(auto_commit_check.get_attribute(
|
||||
'class')):
|
||||
auto_commit_btn.click()
|
||||
self.page.find_by_id("btn-auto-commit").click()
|
||||
|
||||
self.page.find_by_id("btn-flash").click()
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
self.page.click_tab('Messages')
|
||||
self.driver.find_element_by_xpath(
|
||||
self.page.find_by_xpath(
|
||||
'//div[contains(@class, "sql-editor-message") and contains(string(), "CREATE TABLE")]'
|
||||
)
|
||||
|
||||
|
@ -481,7 +304,7 @@ ROLLBACK;"""
|
|||
self.page.find_by_id("btn-flash").click()
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
self.page.click_tab('Messages')
|
||||
self.driver.find_element_by_xpath(
|
||||
self.page.find_by_xpath(
|
||||
'//div[contains(@class, "sql-editor-message") and contains(string(), "ROLLBACK")]'
|
||||
)
|
||||
|
||||
|
@ -503,36 +326,46 @@ SELECT relname FROM pg_class WHERE relkind IN ('r','s','t') and relnamespace = 2
|
|||
assert len(el) == 0, "Table '{}' created with auto commit disabled and without any explicit commit.".format(table_name)
|
||||
|
||||
def _query_tool_auto_commit_enabled(self):
|
||||
|
||||
query = """-- 1. Enable auto commit.
|
||||
-- 2. END any open transaction.
|
||||
-- 3. Create table in public schema.
|
||||
-- 4. ROLLBACK transaction
|
||||
-- 5. Check if table is created event after ROLLBACK.
|
||||
END;"""
|
||||
|
||||
self.page.fill_codemirror_area_with(query)
|
||||
|
||||
wait = WebDriverWait(self.page.driver, 10)
|
||||
|
||||
btn_query_dropdown = wait.until(EC.presence_of_element_located(
|
||||
(By.ID, "btn-query-dropdown")))
|
||||
|
||||
btn_query_dropdown.click()
|
||||
|
||||
self.page.find_by_id("btn-auto-commit").click()
|
||||
|
||||
self.page.find_by_id("btn-flash").click()
|
||||
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
|
||||
self._clear_query_tool()
|
||||
|
||||
table_name = 'query_tool_auto_commit_enabled_table'
|
||||
query = """-- 1. END any open transaction.
|
||||
query = """-- 1. (Done) END any open transaction.
|
||||
-- 2. Enable auto commit.
|
||||
-- 3. Create table in public schema.
|
||||
-- 4. ROLLBACK transaction
|
||||
-- 5. Check if table is created event after ROLLBACK.
|
||||
END;
|
||||
CREATE TABLE public.{}();""".format(table_name)
|
||||
wait = WebDriverWait(self.page.driver, 10)
|
||||
|
||||
self.page.fill_codemirror_area_with(query)
|
||||
|
||||
self.page.find_by_id("btn-query-dropdown").click()
|
||||
|
||||
auto_commit_btn = self.page.find_by_id("btn-auto-commit")
|
||||
|
||||
auto_commit_check = auto_commit_btn.find_element_by_tag_name("i")
|
||||
|
||||
# if auto commit is enabled then 'i' element will
|
||||
# have 'auto-commit fa fa-check' classes
|
||||
# if auto commit is disabled then 'i' element will
|
||||
# have 'auto-commit fa fa-check visibility-hidden' classes
|
||||
|
||||
if 'auto-commit fa fa-check visibility-hidden' == str(auto_commit_check.get_attribute(
|
||||
'class')):
|
||||
auto_commit_btn.click()
|
||||
self.page.find_by_id("btn-flash").click()
|
||||
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
self.page.click_tab('Messages')
|
||||
self.driver.find_element_by_xpath(
|
||||
self.page.find_by_xpath(
|
||||
'//div[contains(@class, "sql-editor-message") and contains(string(), "CREATE TABLE")]'
|
||||
)
|
||||
|
||||
|
@ -547,7 +380,7 @@ ROLLBACK;"""
|
|||
self.page.find_by_id("btn-flash").click()
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
self.page.click_tab('Messages')
|
||||
self.driver.find_element_by_xpath(
|
||||
self.page.find_by_xpath(
|
||||
'//div[contains(@class, "sql-editor-message") and contains(string(), "ROLLBACK")]'
|
||||
)
|
||||
|
||||
|
@ -572,8 +405,8 @@ SELECT relname FROM pg_class WHERE relkind IN ('r','s','t') and relnamespace = 2
|
|||
|
||||
def _query_tool_auto_rollback_enabled(self):
|
||||
table_name = 'query_tool_auto_rollback_enabled_table'
|
||||
query = """-- 1. END any open transaction.
|
||||
-- 2. Enable auto rollback and disable auto commit.
|
||||
query = """-- 1. Enable auto rollback and disable auto commit.
|
||||
-- 2. END any open transaction.
|
||||
-- 3. Create table in public schema.
|
||||
-- 4. Generate error in transaction.
|
||||
-- 5. END transaction.
|
||||
|
@ -581,6 +414,12 @@ SELECT relname FROM pg_class WHERE relkind IN ('r','s','t') and relnamespace = 2
|
|||
END;"""
|
||||
self.page.fill_codemirror_area_with(query)
|
||||
|
||||
self.page.find_by_id("btn-query-dropdown").click()
|
||||
|
||||
self.page.find_by_id("btn-auto-rollback").click()
|
||||
|
||||
self.page.find_by_id("btn-auto-commit").click()
|
||||
|
||||
self.page.find_by_id("btn-flash").click()
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
self._clear_query_tool()
|
||||
|
@ -596,38 +435,10 @@ CREATE TABLE public.{}();""".format(table_name)
|
|||
|
||||
self.page.fill_codemirror_area_with(query)
|
||||
|
||||
self.page.find_by_id("btn-query-dropdown").click()
|
||||
|
||||
auto_rollback_btn = self.page.find_by_id("btn-auto-rollback")
|
||||
|
||||
auto_rollback_check = auto_rollback_btn.find_element_by_tag_name("i")
|
||||
|
||||
# if auto rollback is enabled then 'i' element will
|
||||
# have 'auto-rollback fa fa-check' classes
|
||||
# if auto rollback is disabled then 'i' element will
|
||||
# have 'auto-rollback fa fa-check visibility-hidden' classes
|
||||
|
||||
if 'auto-rollback fa fa-check visibility-hidden' == str(auto_rollback_check.get_attribute(
|
||||
'class')):
|
||||
auto_rollback_btn.click()
|
||||
|
||||
auto_commit_btn = self.page.find_by_id("btn-auto-commit")
|
||||
|
||||
auto_commit_check = auto_commit_btn.find_element_by_tag_name("i")
|
||||
|
||||
# if auto commit is enabled then 'i' element will
|
||||
# have 'auto-commit fa fa-check' classes
|
||||
# if auto commit is disabled then 'i' element will
|
||||
# have 'auto-commit fa fa-check visibility-hidden' classes
|
||||
|
||||
if 'auto-commit fa fa-check' == str(auto_commit_check.get_attribute(
|
||||
'class')):
|
||||
auto_commit_btn.click()
|
||||
|
||||
self.page.find_by_id("btn-flash").click()
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
self.page.click_tab('Messages')
|
||||
self.driver.find_element_by_xpath(
|
||||
self.page.find_by_xpath(
|
||||
'//div[contains(@class, "sql-editor-message") and contains(string(), "CREATE TABLE")]'
|
||||
)
|
||||
|
||||
|
|
|
@ -199,8 +199,6 @@ CREATE TABLE public.defaults
|
|||
self.page.toggle_open_tree_item(self.server['name'])
|
||||
self.page.toggle_open_tree_item('Databases')
|
||||
self.page.toggle_open_tree_item('acceptance_test_db')
|
||||
# wait until all database dependant modules/js are loaded.
|
||||
time.sleep(5)
|
||||
self.page.toggle_open_tree_item('Schemas')
|
||||
self.page.toggle_open_tree_item('public')
|
||||
self.page.toggle_open_tree_item('Tables')
|
||||
|
@ -267,7 +265,7 @@ CREATE TABLE public.defaults
|
|||
cell_xpath = CheckForViewDataTest._get_cell_xpath(
|
||||
'r'+str(idx), 1
|
||||
)
|
||||
time.sleep(0.4)
|
||||
time.sleep(0.2)
|
||||
self._update_cell(cell_xpath, config_data[str(idx)])
|
||||
|
||||
self.page.find_by_id("btn-save").click() # Save data
|
||||
|
@ -300,4 +298,4 @@ CREATE TABLE public.defaults
|
|||
if idx != 1 and not is_new_row:
|
||||
self.assertEquals(cells[idx], config_data[str(idx)][1])
|
||||
elif is_new_row:
|
||||
self.assertEquals(cells[idx], config_data[str(idx)][1])
|
||||
self.assertEquals(cells[idx], config_data[str(idx)][1])
|
||||
|
|
|
@ -7,13 +7,9 @@
|
|||
#
|
||||
##########################################################################
|
||||
|
||||
from selenium.webdriver import ActionChains
|
||||
from regression.python_test_utils import test_utils
|
||||
from regression.feature_utils.base_feature_test import BaseFeatureTest
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
from selenium.webdriver.common.by import By
|
||||
import time
|
||||
|
||||
|
||||
class CheckForXssFeatureTest(BaseFeatureTest):
|
||||
"""
|
||||
|
@ -53,7 +49,7 @@ class CheckForXssFeatureTest(BaseFeatureTest):
|
|||
|
||||
def runTest(self):
|
||||
self.page.wait_for_spinner_to_disappear()
|
||||
self._connects_to_server()
|
||||
self.page.add_server(self.server)
|
||||
self._tables_node_expandable()
|
||||
self._check_xss_in_browser_tree()
|
||||
self._check_xss_in_properties_tab()
|
||||
|
@ -65,7 +61,6 @@ class CheckForXssFeatureTest(BaseFeatureTest):
|
|||
self.page.close_query_tool()
|
||||
|
||||
def after(self):
|
||||
time.sleep(1)
|
||||
self.page.remove_server(self.server)
|
||||
connection = test_utils.get_db_connection(self.server['db'],
|
||||
self.server['username'],
|
||||
|
@ -75,24 +70,6 @@ class CheckForXssFeatureTest(BaseFeatureTest):
|
|||
self.server['sslmode'])
|
||||
test_utils.drop_database(connection, "acceptance_test_db")
|
||||
|
||||
def _connects_to_server(self):
|
||||
self.page.find_by_xpath("//*[@class='aciTreeText' and .='Servers']").click()
|
||||
time.sleep(2)
|
||||
self.page.driver.find_element_by_link_text("Object").click()
|
||||
ActionChains(self.page.driver) \
|
||||
.move_to_element(self.page.driver.find_element_by_link_text("Create")) \
|
||||
.perform()
|
||||
self.page.find_by_partial_link_text("Server...").click()
|
||||
|
||||
server_config = self.server
|
||||
self.page.fill_input_by_field_name("name", server_config['name'])
|
||||
self.page.find_by_partial_link_text("Connection").click()
|
||||
self.page.fill_input_by_field_name("host", server_config['host'])
|
||||
self.page.fill_input_by_field_name("port", server_config['port'])
|
||||
self.page.fill_input_by_field_name("username", server_config['username'])
|
||||
self.page.fill_input_by_field_name("password", server_config['db_password'])
|
||||
self.page.find_by_xpath("//button[contains(.,'Save')]").click()
|
||||
|
||||
def _tables_node_expandable(self):
|
||||
self.page.toggle_open_server(self.server['name'])
|
||||
self.page.toggle_open_tree_item('Databases')
|
||||
|
@ -155,10 +132,10 @@ class CheckForXssFeatureTest(BaseFeatureTest):
|
|||
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 -')
|
||||
self.page.fill_codemirror_area_with("select '<img src=\"x\" onerror=\"console.log(1)\">'")
|
||||
time.sleep(1)
|
||||
self.page.fill_codemirror_area_with(
|
||||
"select '<img src=\"x\" onerror=\"console.log(1)\">'"
|
||||
)
|
||||
self.page.find_by_id("btn-flash").click()
|
||||
wait = WebDriverWait(self.page.driver, 5)
|
||||
|
||||
result_row = self.page.find_by_xpath(
|
||||
"//*[contains(@class, 'ui-widget-content') and contains(@style, 'top:0px')]"
|
||||
|
@ -177,9 +154,4 @@ class CheckForXssFeatureTest(BaseFeatureTest):
|
|||
|
||||
def _check_escaped_characters(self, source_code, string_to_find, source):
|
||||
# For XSS we need to search against element's html code
|
||||
if source_code.find(string_to_find) == -1:
|
||||
# No escaped characters found
|
||||
assert False, "{0} might be vulnerable to XSS ".format(source)
|
||||
else:
|
||||
# escaped characters found
|
||||
assert True
|
||||
assert source_code.find(string_to_find) != -1, "{0} might be vulnerable to XSS ".format(source)
|
||||
|
|
|
@ -8,9 +8,13 @@
|
|||
##########################################################################
|
||||
|
||||
from selenium.webdriver import ActionChains
|
||||
from selenium.common.exceptions import TimeoutException
|
||||
from regression.python_test_utils import test_utils
|
||||
from regression.feature_utils.base_feature_test import BaseFeatureTest
|
||||
import time
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
|
||||
class CheckDebuggerForXssFeatureTest(BaseFeatureTest):
|
||||
"""Tests to check if Debugger is vulnerable to XSS."""
|
||||
|
@ -30,34 +34,15 @@ class CheckDebuggerForXssFeatureTest(BaseFeatureTest):
|
|||
|
||||
def runTest(self):
|
||||
self.page.wait_for_spinner_to_disappear()
|
||||
self._connects_to_server()
|
||||
self.page.add_server(self.server)
|
||||
self._function_node_expandable()
|
||||
self._debug_function()
|
||||
|
||||
def after(self):
|
||||
time.sleep(0.5)
|
||||
test_utils.drop_debug_function(self.server, "postgres",
|
||||
"test_function")
|
||||
self.page.remove_server(self.server)
|
||||
|
||||
def _connects_to_server(self):
|
||||
self.page.find_by_xpath("//*[@class='aciTreeText' and .='Servers']").click()
|
||||
time.sleep(2)
|
||||
self.page.driver.find_element_by_link_text("Object").click()
|
||||
ActionChains(self.page.driver) \
|
||||
.move_to_element(self.page.driver.find_element_by_link_text("Create")) \
|
||||
.perform()
|
||||
self.page.find_by_partial_link_text("Server...").click()
|
||||
|
||||
server_config = self.server
|
||||
self.page.fill_input_by_field_name("name", server_config['name'])
|
||||
self.page.find_by_partial_link_text("Connection").click()
|
||||
self.page.fill_input_by_field_name("host", server_config['host'])
|
||||
self.page.fill_input_by_field_name("port", server_config['port'])
|
||||
self.page.fill_input_by_field_name("username", server_config['username'])
|
||||
self.page.fill_input_by_field_name("password", server_config['db_password'])
|
||||
self.page.find_by_xpath("//button[contains(.,'Save')]").click()
|
||||
|
||||
def _function_node_expandable(self):
|
||||
self.page.toggle_open_server(self.server['name'])
|
||||
self.page.toggle_open_tree_item('Databases')
|
||||
|
@ -73,32 +58,44 @@ class CheckDebuggerForXssFeatureTest(BaseFeatureTest):
|
|||
.move_to_element(self.page.driver.find_element_by_link_text("Debugging")) \
|
||||
.perform()
|
||||
self.page.driver.find_element_by_link_text("Debug").click()
|
||||
time.sleep(0.5)
|
||||
|
||||
# We need to check if debugger plugin is installed or not
|
||||
try:
|
||||
is_error = self.page.find_by_xpath(
|
||||
"//div[contains(@class,'ajs-header')]"
|
||||
).text
|
||||
except Exception as e:
|
||||
wait = WebDriverWait(self.page.driver, 2)
|
||||
is_error = wait.until(EC.presence_of_element_located(
|
||||
(By.XPATH, "//div[contains(@class,'ajs-header')]"))
|
||||
)
|
||||
except TimeoutException as e:
|
||||
is_error = None
|
||||
|
||||
# If debugger plugin is not found
|
||||
if is_error and is_error == "Debugger Error":
|
||||
if is_error and is_error.text == "Debugger Error":
|
||||
self.page.click_modal('OK')
|
||||
self.skipTest("Please make sure that debugger plugin is properly configured")
|
||||
self.skipTest(
|
||||
"Please make sure that debugger plugin is properly configured"
|
||||
)
|
||||
else:
|
||||
time.sleep(2)
|
||||
self.page.driver.switch_to.frame(self.page.driver.find_element_by_tag_name('iframe'))
|
||||
self.page.click_element(self.page.driver.find_elements_by_xpath("//button")[2])
|
||||
time.sleep(2)
|
||||
self.page.driver.switch_to.frame(
|
||||
self.page.driver.find_element_by_tag_name('iframe')
|
||||
)
|
||||
|
||||
# Only this tab is vulnerable rest are BackGrid & Code Mirror control
|
||||
# which are already tested in Query tool test case
|
||||
wait.until(EC.presence_of_element_located(
|
||||
(By.XPATH, "//span[contains(.,'Hello, pgAdmin4')]"))
|
||||
)
|
||||
self.page.click_element(
|
||||
self.page.driver.find_elements_by_xpath("//button")[2]
|
||||
)
|
||||
|
||||
wait.until(EC.presence_of_element_located(
|
||||
(By.XPATH, "//td[contains(@class,'test_function') and contains(.,'Hello, pgAdmin4')]"))
|
||||
)
|
||||
|
||||
# Only this tab is vulnerable rest are BackGrid & Code Mirror
|
||||
# control which are already tested in Query tool test case
|
||||
self.page.click_tab("Messages")
|
||||
source_code = self.page.find_by_xpath(
|
||||
"//*[@id='messages']"
|
||||
).get_attribute('innerHTML')
|
||||
|
||||
self._check_escaped_characters(
|
||||
source_code,
|
||||
'NOTICE: <img src="x" onerror="console.log(1)">',
|
||||
|
@ -107,18 +104,11 @@ class CheckDebuggerForXssFeatureTest(BaseFeatureTest):
|
|||
self._close_debugger()
|
||||
|
||||
def _close_debugger(self):
|
||||
time.sleep(0.5)
|
||||
self.page.driver.switch_to_default_content()
|
||||
time.sleep(0.5)
|
||||
self.page.click_element(
|
||||
self.page.find_by_xpath("//*[@id='dockerContainer']/div/div[3]/div/div[2]/div[1]")
|
||||
)
|
||||
|
||||
def _check_escaped_characters(self, source_code, string_to_find, source):
|
||||
# For XSS we need to search against element's html code
|
||||
if source_code.find(string_to_find) == -1:
|
||||
# No escaped characters found
|
||||
assert False, "{0} might be vulnerable to XSS ".format(source)
|
||||
else:
|
||||
# escaped characters found
|
||||
assert True
|
||||
assert source_code.find(string_to_find) != -1, "{0} might be vulnerable to XSS ".format(source)
|
||||
|
|
|
@ -11,6 +11,7 @@ from selenium.webdriver import ActionChains
|
|||
from regression.python_test_utils import test_utils
|
||||
from regression.feature_utils.base_feature_test import BaseFeatureTest
|
||||
|
||||
|
||||
class CheckRoleMembershipControlFeatureTest(BaseFeatureTest):
|
||||
"""Tests to check role membership control for xss."""
|
||||
|
||||
|
@ -22,9 +23,9 @@ class CheckRoleMembershipControlFeatureTest(BaseFeatureTest):
|
|||
def before(self):
|
||||
# Some test function is needed for debugger
|
||||
test_utils.create_role(self.server, "postgres",
|
||||
"test_role")
|
||||
"test_role")
|
||||
test_utils.create_role(self.server, "postgres",
|
||||
"<h1>test</h1>")
|
||||
"<h1>test</h1>")
|
||||
|
||||
def runTest(self):
|
||||
self.page.wait_for_spinner_to_disappear()
|
||||
|
@ -34,9 +35,9 @@ class CheckRoleMembershipControlFeatureTest(BaseFeatureTest):
|
|||
|
||||
def after(self):
|
||||
test_utils.drop_role(self.server, "postgres",
|
||||
"test_role")
|
||||
"test_role")
|
||||
test_utils.drop_role(self.server, "postgres",
|
||||
"<h1>test</h1>")
|
||||
"<h1>test</h1>")
|
||||
self.page.remove_server(self.server)
|
||||
|
||||
def _connects_to_server(self):
|
||||
|
@ -77,12 +78,6 @@ class CheckRoleMembershipControlFeatureTest(BaseFeatureTest):
|
|||
)
|
||||
self.page.find_by_xpath("//button[contains(.,'Cancel')]").click()
|
||||
|
||||
|
||||
def _check_escaped_characters(self, source_code, string_to_find, source):
|
||||
# For XSS we need to search against element's html code
|
||||
if source_code.find(string_to_find) == -1:
|
||||
# No escaped characters found
|
||||
assert False, "{0} might be vulnerable to XSS ".format(source)
|
||||
else:
|
||||
# escaped characters found
|
||||
assert True
|
||||
assert source_code.find(string_to_find) != -1, "{0} might be vulnerable to XSS ".format(source)
|
||||
|
|
|
@ -8,10 +8,9 @@
|
|||
##########################################################################
|
||||
|
||||
import time
|
||||
import math
|
||||
|
||||
from selenium.common.exceptions import NoSuchElementException, \
|
||||
WebDriverException, StaleElementReferenceException
|
||||
WebDriverException
|
||||
from selenium.webdriver import ActionChains
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
|
@ -180,9 +179,6 @@ class PgadminPage:
|
|||
self.wait_for_input_field_content(field_name, field_content)
|
||||
|
||||
def fill_codemirror_area_with(self, field_content):
|
||||
# For long text, if we try to execute send_keys and perform back to back, then the actions are
|
||||
# not executed properly as the driver can send only 50 to 60 characters. To avoid this, sleep
|
||||
# on the basis of content length.
|
||||
def find_codemirror(driver):
|
||||
try:
|
||||
driver.switch_to.default_content()
|
||||
|
@ -203,8 +199,6 @@ class PgadminPage:
|
|||
action = ActionChains(self.driver)
|
||||
action.send_keys(field_content)
|
||||
action.perform()
|
||||
sleep_time = math.ceil(len(field_content) / 50)
|
||||
time.sleep(sleep_time)
|
||||
|
||||
def click_tab(self, tab_name):
|
||||
tab = self.find_by_xpath("//*[contains(@class,'wcTabTop')]//*[contains(@class,'wcPanelTab') "
|
||||
|
|
Loading…
Reference in New Issue