From ed4a98edf33b6dc15b47580557835d00c3ef31c6 Mon Sep 17 00:00:00 2001 From: axuan Date: Fri, 25 Oct 2024 17:23:42 +0800 Subject: [PATCH] add case for advance search: Sort search result by extended sortable fields --- features/advance_search.feature | 5 ++ features/pages/advanced_search_page.py | 66 +++++++++++++++++++++++++- features/pages/flaw_detail_page.py | 7 ++- features/steps/advance_search.py | 40 +++++++++++++++- 4 files changed, 113 insertions(+), 5 deletions(-) diff --git a/features/advance_search.feature b/features/advance_search.feature index 76e3a4624..4a1bd6d45 100644 --- a/features/advance_search.feature +++ b/features/advance_search.feature @@ -42,5 +42,10 @@ Feature: Flaw advance search testing Given I go to the advanced search page Then I am able to search flaws with osidb related models in query filter + Scenario: Sort search result by extended sortable fields + Given I go to the advanced search page + When I sort search result by extended sortable field + Then I got search result sorted by extended field + Scenario: Search flaws with both query filter and selected field Then I am able to search flaws with both query filter and selected field diff --git a/features/pages/advanced_search_page.py b/features/pages/advanced_search_page.py index 6077ed04b..68653cf2e 100644 --- a/features/pages/advanced_search_page.py +++ b/features/pages/advanced_search_page.py @@ -1,6 +1,13 @@ -from features.pages.base import BasePage +import time +from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys +from selenium.webdriver.common.action_chains import ActionChains +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.support.wait import WebDriverWait + +from features.pages.base import BasePage +from features.pages.flaw_detail_page import FlawDetailPage class AdvancedSearchPage(BasePage): @@ -32,6 +39,11 @@ def __init__(self, driver): "embargoedFlag": ("XPATH", "(//span[contains(text(), 'Embargoed')])[1]"), "queryFilterInput": ("XPATH", "(//div[@class='input-group my-1'])[1]/textarea"), "defaultFilterSavedMsg": ("XPATH", "//div[contains(text(), 'default filter saved')]"), + + "createdBtn": ("XPATH", "//thead[@class='sticky-top']/tr/th[contains(text(), 'Created')]"), + "extendSortSelect": ("XPATH", "//select[@title='When using this sorting with active table column sort," + " the table column field will be used as secondary sorting key']"), + "extendSortOrderBtn": ("XPATH", "//button[@class='sort-by-order btn btn-sm']"), } def first_flaw_exist(self): @@ -74,3 +86,55 @@ def set_query_filter(self, value): if value: self.driver.execute_script("arguments[0].value = '';", filter_input) filter_input.send_keys(value) + + def get_specified_field_search_result(self, field_name, n=5): + flaws = self.driver.find_elements(By.XPATH, "//tbody[@class='table-group-divider']/tr") + count = 0 + result = [] + + flaw_detail_page = FlawDetailPage(self.driver) + + wait = WebDriverWait(self.driver, 10) + + for flaw in flaws: + if count == n: + break + tds = flaw.find_elements(By.XPATH, './td') + if len(tds) < 6: + continue + + # Store the ID of the original window + original_window = self.driver.current_window_handle + + link = tds[0].find_element(By.XPATH, './a') + + # open link with a new tab + (ActionChains(self.driver).key_down(Keys.LEFT_CONTROL). + click(link).key_up(Keys.LEFT_CONTROL).perform()) + + # Wait for the new window or tab + wait.until(EC.number_of_windows_to_be(2)) + + # switch to new tab + self.driver.switch_to.window(self.driver.window_handles[1]) + time.sleep(3) + + # get data + value = "" + if field_name == "cvss_scores__score": + value = flaw_detail_page.get_cvssV3_score() + elif field_name == "cwe_id": + value = flaw_detail_page.get_input_field_value_using_relative_locator("cweidText") + elif field_name == "major_incident_state": + value = flaw_detail_page.get_select_value_using_relative_locator("incidentStateText") + elif field_name == "source": + value = flaw_detail_page.get_select_value_using_relative_locator("sourceText") + + # close tab and back to search page + self.driver.close() + self.driver.switch_to.window(original_window) + + result.append(value) + count += 1 + + return result diff --git a/features/pages/flaw_detail_page.py b/features/pages/flaw_detail_page.py index f0928fb06..7dade9284 100644 --- a/features/pages/flaw_detail_page.py +++ b/features/pages/flaw_detail_page.py @@ -766,8 +766,11 @@ def set_reject_reason(self, value): def get_select_value_using_relative_locator(self, field): element = getattr(self, field) field_select = self.driver.find_elements( - locate_with(By.XPATH, "//select[@class='form-select']").near(element))[0] - selected_item = field_select.get_list_selected_item() + locate_with(By.XPATH, "//select[@class='form-select']").near(element)) + if not field_select: + field_select = self.driver.find_elements( + locate_with(By.XPATH, "//select[@class='form-select is-invalid']").near(element)) + selected_item = field_select[0].get_list_selected_item() current_value = selected_item[0] if selected_item else None return current_value diff --git a/features/steps/advance_search.py b/features/steps/advance_search.py index c083204ac..4cfba0a50 100644 --- a/features/steps/advance_search.py +++ b/features/steps/advance_search.py @@ -7,8 +7,7 @@ from features.common_utils import get_data_from_tmp_data_file from features.steps.common_steps import go_to_specific_flaw_detail_page from features.constants import EMBARGOED_FLAW_UUID_KEY, FLAW_ID_KEY -from features.utils import go_to_advanced_search_page - +from features.utils import go_to_advanced_search_page, is_sorted EMPTY_FIELDS = [ "cve_description", @@ -220,6 +219,43 @@ def step_impl(context): flaw_page.check_text_exist(v) +@when('I sort search result by extended sortable field') +def step_impl(context): + advanced_search_page = AdvancedSearchPage(context.browser) + # click created order twice, let result not sort by table column + advanced_search_page.click_btn("createdBtn") + advanced_search_page.click_btn('createdBtn') + advanced_search_page.first_flaw_exist() + + select_value_list = ["cvss_scores__score", "cwe_id", "major_incident_state", "source"] + result_dict = {} + + # ascending + for select_value in select_value_list: + advanced_search_page.extendSortSelect.select_element_by_value(select_value) + time.sleep(3) + res = advanced_search_page.get_specified_field_search_result(select_value) + result_dict[select_value] = {"asce": res} + + advanced_search_page.extendSortOrderBtn.click_button() + # descending + for select_value in select_value_list: + advanced_search_page.extendSortSelect.select_element_by_value(select_value) + time.sleep(3) + res = advanced_search_page.get_specified_field_search_result(select_value) + result_dict[select_value]["desc"] = res + + context.result_dict = result_dict + + +@then('I got search result sorted by extended field') +def step_impl(context): + for k, v in context.result_dict.items(): + for order, values in v.items(): + assert is_sorted(values, order) is True, f"Sort by field {k} in {order} failed. Get: {values}" + + + @then('I am able to search flaws with both query filter and selected field') def step_impl(context): # get flaw data for search