From 63ea562d803fa523f6f9a364b2d2ba38a5c0d858 Mon Sep 17 00:00:00 2001 From: Satellite QE <115476073+Satellite-QE@users.noreply.github.com> Date: Tue, 19 Dec 2023 07:37:56 -0500 Subject: [PATCH] Vertical navigation search widget & function (#1076) (#1089) Added new widget(s) for PF4 vertical navigation search. New method `BaseEntity.search_menu()`. (cherry picked from commit 16433b57f3cc874b07c54bfac19e99034c6e4bb6) Co-authored-by: Pavel Novotny --- airgun/entities/base.py | 9 +++++++ airgun/views/common.py | 2 ++ airgun/widgets.py | 58 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/airgun/entities/base.py b/airgun/entities/base.py index 27b6015e9..9d12502e2 100644 --- a/airgun/entities/base.py +++ b/airgun/entities/base.py @@ -48,3 +48,12 @@ def create_bookmark(self, values, search_query=None): view.submit.click() view.flash.assert_no_error() view.flash.dismiss() + + def search_menu(self, query: str) -> list[str]: + """Perform a search of the vertical navigation menu. + + :param str query: search query for the vertical navigation menu + :return list[str]: search results + """ + view = self.navigate_to(self, 'All') + return view.menu_search.search(query) diff --git a/airgun/views/common.py b/airgun/views/common.py index ffe15a9cc..99d0ec676 100644 --- a/airgun/views/common.py +++ b/airgun/views/common.py @@ -25,6 +25,7 @@ ItemsList, LCESelector, Pf4ConfirmationDialog, + PF4NavSearch, PF4Search, ProgressBar, ReadOnlyEntry, @@ -40,6 +41,7 @@ class BaseLoggedInView(View): """Base view for Satellite pages""" menu = Navigation("Global") + menu_search = PF4NavSearch() taxonomies = ContextSelector() flash = SatFlashMessages() validations = ValidationErrors() diff --git a/airgun/widgets.py b/airgun/widgets.py index 38b216c78..03867ddc0 100644 --- a/airgun/widgets.py +++ b/airgun/widgets.py @@ -27,7 +27,7 @@ VerticalNavigation, ) from widgetastic_patternfly4 import Pagination as PF4Pagination -from widgetastic_patternfly4.ouia import BaseSelect, Button as PF4Button, Dropdown +from widgetastic_patternfly4.ouia import BaseSelect, Button as PF4Button, Dropdown, Menu from widgetastic_patternfly4.progress import Progress as PF4Progress from airgun.exceptions import DisabledWidgetError, ReadOnlyWidgetError @@ -835,6 +835,62 @@ def search(self, value): self.search_button.click() +class PF4NavSearchMenu(Menu): + """PF4 vertical navigation dropdown menu with search results.""" + + @property + def items(self): + """Return list of :py:class:`WebElement` items in the menu.""" + return self.browser.elements(self.ITEMS_LOCATOR) + + def read(self): + """Return all items in the menu as strings.""" + return [self.browser.text(el) for el in self.items] + + +class PF4NavSearch(PF4Search): + """PF4 vertical navigation menu search""" + + ROOT = '//div[@id="navigation-search"]' + search_field = TextInput(locator=(".//input[@aria-label='Search input']")) + search_button = Button(locator=(".//button[@aria-label='Search']")) + clear_button = Button(locator=(".//button[@aria-label='Reset']")) + items = PF4NavSearchMenu("navigation-search-menu") + results_timeout = 2 + + def _wait_for_results(self, results_widget): + """Read the search results widget `results_widget` for `self.results_timeout` seconds + and return the values. If timeout is exceeded, empty list is returned. + + :return: list[str] if values are returned; empty list otherwise + """ + return ( + wait_for( + lambda: results_widget.read(), + timeout=self.results_timeout, + delay=0.5, + handle_exception=NoSuchElementException, + silent_failure=True, + )[0] + or [] + ) + + def search(self, value): + """Search the vertical navigation menu. + The first clear() is a workaround for inconsistent behaviour (mostly in Chrome), + where the previous value is sometimes still shown. + Clear the input field afterward, so it does not interfere with the regular navigation menu. + + :param str value: search query + :return: list of search results as strings + """ + self.clear() + super().search(value) + results = self._wait_for_results(results_widget=self.items) + self.clear() + return results + + class SatVerticalNavigation(VerticalNavigation): """The Patternfly Vertical navigation."""