diff --git a/airgun/entities/about.py b/airgun/entities/about.py new file mode 100644 index 000000000..48cf47092 --- /dev/null +++ b/airgun/entities/about.py @@ -0,0 +1,19 @@ +from airgun.entities.base import BaseEntity +from airgun.navigation import NavigateStep, navigator +from airgun.utils import retry_navigation +from airgun.views.about import AboutView + + +class AboutEntity(BaseEntity): + endpoint_path = '/about' + + +@navigator.register(AboutEntity, 'All') +class ShowAboutPage(NavigateStep): + """Navigate to About page.""" + + VIEW = AboutView + + @retry_navigation + def step(self, *args, **kwargs): + self.view.menu.select('Administer', 'About') diff --git a/airgun/entities/fact_value.py b/airgun/entities/fact_value.py new file mode 100644 index 000000000..bb82c0e42 --- /dev/null +++ b/airgun/entities/fact_value.py @@ -0,0 +1,19 @@ +from airgun.entities.base import BaseEntity +from airgun.navigation import NavigateStep, navigator +from airgun.utils import retry_navigation +from airgun.views.fact import HostFactView + + +class FactValueEntity(BaseEntity): + endpoint_path = '/fact_values' + + +@navigator.register(FactValueEntity, 'All') +class ShowFactValuePage(NavigateStep): + """Navigate to Fact Values page.""" + + VIEW = HostFactView + + @retry_navigation + def step(self, *args, **kwargs): + self.view.menu.select('Monitor', 'Facts') diff --git a/airgun/entities/global_parameter.py b/airgun/entities/global_parameter.py new file mode 100644 index 000000000..ab847bc20 --- /dev/null +++ b/airgun/entities/global_parameter.py @@ -0,0 +1,19 @@ +from airgun.entities.base import BaseEntity +from airgun.navigation import NavigateStep, navigator +from airgun.utils import retry_navigation +from airgun.views.global_parameter import GlobalParameterView + + +class GlobalParameterEntity(BaseEntity): + endpoint_path = '/common_parameters' + + +@navigator.register(GlobalParameterEntity, 'All') +class ShowGlobalParameters(NavigateStep): + """Navigate to Global Parameters page.""" + + VIEW = GlobalParameterView + + @retry_navigation + def step(self, *args, **kwargs): + self.view.menu.select('Configure', 'Global Parameters') diff --git a/airgun/session.py b/airgun/session.py index 229ea558c..7e1eaaee1 100644 --- a/airgun/session.py +++ b/airgun/session.py @@ -10,6 +10,7 @@ from airgun import settings from airgun.browser import AirgunBrowser, SeleniumBrowserFactory +from airgun.entities.about import AboutEntity from airgun.entities.acs import AcsEntity from airgun.entities.activationkey import ActivationKeyEntity from airgun.entities.all_hosts import AllHostsEntity @@ -37,8 +38,10 @@ from airgun.entities.domain import DomainEntity from airgun.entities.eol_banner import EOLBannerEntity from airgun.entities.errata import ErrataEntity +from airgun.entities.fact_value import FactValueEntity from airgun.entities.file import FilesEntity from airgun.entities.filter import FilterEntity +from airgun.entities.global_parameter import GlobalParameterEntity from airgun.entities.hardware_model import HardwareModelEntity from airgun.entities.host import HostEntity from airgun.entities.host_new import NewHostEntity @@ -328,6 +331,11 @@ def acs(self): """Instance of Alternate Content Sources entity.""" return self._open(AcsEntity) + @cached_property + def about(self): + """Instance of About entity.""" + return self._open(AboutEntity) + @cached_property def activationkey(self): """Instance of Activation Key entity.""" @@ -457,6 +465,11 @@ def errata(self): """Instance of Errata entity.""" return self._open(ErrataEntity) + @cached_property + def factvalue(self): + """Instance of Fact Value entity.""" + return self._open(FactValueEntity) + @cached_property def filter(self): """Instance of Filter entity.""" @@ -467,6 +480,11 @@ def file(self): """Instance of Files entity.""" return self._open(FilesEntity) + @cached_property + def global_parameter(self): + """Instance of Global Parameters entity.""" + return self._open(GlobalParameterEntity) + @cached_property def hardwaremodel(self): """Instance of Hardware Model entity.""" diff --git a/airgun/views/about.py b/airgun/views/about.py new file mode 100644 index 000000000..575f9226e --- /dev/null +++ b/airgun/views/about.py @@ -0,0 +1,11 @@ +from widgetastic.widget import Text + +from airgun.views.common import BaseLoggedInView, SearchableViewMixinPF4 + + +class AboutView(BaseLoggedInView, SearchableViewMixinPF4): + title = Text("//h1[normalize-space(.)='About']") + + @property + def is_displayed(self): + return self.browser.wait_for_element(self.title, exception=False) is not None diff --git a/airgun/views/common.py b/airgun/views/common.py index 2419e9428..e09166c4b 100644 --- a/airgun/views/common.py +++ b/airgun/views/common.py @@ -1,3 +1,4 @@ +from selenium.common.exceptions import ElementNotInteractableException from widgetastic.widget import ( Checkbox, ConditionalSwitchableView, @@ -80,6 +81,35 @@ def read(self, widget_names=None, limit=None): values[widget_name] = widget.read() return normalize_dict_values(values) + def documentation_links(self): + """Return Documentation links present on the given page if any. + Note: This is not a full-proof helper. For example, it can't get links hidden behind a dropdown button. + """ + doc_link_elements = ( + '//a[contains(text(), "documentation") or contains(text(), "Documentation") or ' + 'contains(@class, "btn-docs") or contains(@href, "console.redhat.com") or ' + 'contains(@href, "access.redhat.com") or contains(@href, "docs.redhat.com") or ' + 'contains(@href, "www.redhat.com") or contains(@href, "links")]' + ) + doc_links = [] + for item in self.browser.elements(doc_link_elements): + try: + item.click() + if len(self.browser.window_handles) == 1: + doc_links.extend([self.browser.url]) + self.browser.selenium.back() + else: + self.browser.switch_to_window(self.browser.window_handles[1]) + doc_links.extend([self.browser.url]) + self.browser.switch_to_window(self.browser.window_handles[0]) + self.browser.close_window(self.browser.window_handles[1]) + except ElementNotInteractableException: + # Adding this because some links are hidden behind dropdown button. + # To Do: Handle doc buttons hidden behind drop down buttons. + doc_links.extend([item.get_attribute('href')]) + continue + return doc_links + class WrongContextAlert(View): """Alert screen which appears when switching organization while organization-specific entity is diff --git a/airgun/views/global_parameter.py b/airgun/views/global_parameter.py new file mode 100644 index 000000000..1ecf0c8b9 --- /dev/null +++ b/airgun/views/global_parameter.py @@ -0,0 +1,11 @@ +from widgetastic.widget import Text + +from airgun.views.common import BaseLoggedInView, SearchableViewMixinPF4 + + +class GlobalParameterView(BaseLoggedInView, SearchableViewMixinPF4): + title = Text("//h1[normalize-space(.)='Global Parameters']") + + @property + def is_displayed(self): + return self.browser.wait_for_element(self.title, exception=False) is not None