class TestView(View): kebab = Kebab(".//h4[@id='dropdown-with-kebab']/following::div" "/div[contains(@class, 'pf-c-dropdown')]") dropdown_txt_locator = Dropdown("Dropdown") dropdown_custom_locator = Dropdown( locator=(".//h4[@id='simple-dropdown']/following::div" "/div[contains(@class, 'pf-c-dropdown')]")) dropdown_default_locator = Dropdown()
class TestView(View): ROOT = ".//h2[normalize-space(.)='Simple dropdown']/following-sibling::div[1]" dropdown_txt_locator = Dropdown("Dropdown") dropdown_custom_locator = Dropdown( locator=".//div[contains(@class, 'pf-c-dropdown')]") dropdown_default_locator = Dropdown() group_dropdown = GroupDropdown(locator=( "//h2[normalize-space(.)='Dropdown with groups']/following-sibling::div[1]" "//div[contains(@class, 'pf-c-dropdown')]"))
class CustomLabelsView(BaseLoggedInPage): """This view represents Custom labels tab page""" paginator = Pagination( locator='.//div[contains(@class, "pf-c-pagination")]') add_label_button = Button("Add label") search = Input(locator=".//input[@aria-label='Filter by short path']") table_loading = './/div[contains(@class, "pf-c-skeleton")]' ACTIONS_INDEX = 2 table = Table( locator='.//table[contains(@aria-label, "Table")]', column_widgets={ "Short path": Button(locator='.//th[@data-label="Short path"]/button'), ACTIONS_INDEX: Dropdown(), }, ) def is_table_loaded(self): return wait_for( lambda: not self.browser.is_displayed(self.table_loading), delay=10, timeout=120) @property def is_displayed(self): if self.is_table_loaded(): return self.add_label_button.is_displayed and self.table.is_displayed else: return False
class SystemRulesView(BaseLoggedInPage): """This view represents System rules tab page""" paginator = Pagination( locator='.//div[contains(@class, "pf-c-pagination")]') show_all_rules = Text(".//input[@id='showAllRules']") table = Table( locator='.//table[contains(@aria-label, "Table")]', column_widgets={ "Provider ID": Button(locator='.//th[@data-label="Provider ID"]/button'), "Number of rules": Button(locator=".//th[@data-label='Number of rules']/button"), 4: Dropdown(), }, ) filter_type_selector = DropdownMenu( locator='.//div[contains(@class, "pf-c-select")]') filter_by = MTACheckboxSelect( locator='.//span[@class="pf-c-select__toggle-arrow"]//parent::button[' 'contains(@aria-labelledby, "Filter by Source")]/parent::div |' ' .//span[@class="pf-c-select__toggle-arrow"]//parent::button[' 'contains(@aria-labelledby, "Filter by Target")]/parent::div') clear = Text('.//button[contains(text(), "Clear all filters")]') @property def is_displayed(self): return self.table.is_displayed and self.show_all_rules.is_displayed
class ApplicationsView(BaseLoggedInPage): title = Text(locator=".//div/h2[normalize-space(.)='Applications']") ACTIONS_INDEX = 2 table = PatternflyTable( ".//table[contains(@class, 'pf-c-table')]", column_widgets={ "Application": Text(locator=".//a"), "Date added": Text(locator=".//td[@data-label='Date added']"), ACTIONS_INDEX: Dropdown(), }, ) add_application_button = Button("Add application") upload_file = HiddenFileInput( locator='.//input[@accept=".ear, .har, .jar, .rar, .sar, .war, .zip"]' ) search = Input(locator=".//input[@aria-label='Filter by name']") done_button = Button("Close") application_packages = Text( locator=".//wu-select-packages/h3[normalize-space(.)='Application packages']" ) sort_application = Text(locator=".//th[contains(normalize-space(.), 'Application')]//i[1]") save_and_run_button = Button("Save and run") delete_button = Button("Delete") cancel_button = Button("Cancel") @property def is_displayed(self): return self.add_application_button.is_displayed and self.title.is_displayed def clear_search(self): """Clear search""" if self.search.value: self.search.fill("")
class LoginPage(View): username = Input(id="username") password = Input(id="password") login_button = Text(locator=".//div/input[@id='kc-login']") header = Text(locator=".//img[@alt='brand']") logout_button = Dropdown(text="mta") def validate_url(self): """The logged in Page in both web console and operator are same so added a url check to differentiate in the view""" if self.context["object"].application.mta_context == "ViaOperatorUI": url = self.context["object"].application.ocphostname elif self.context["object"].application.mta_context == "ViaSecure": url = self.context["object"].application.ocpsecurehostname elif self.context["object"].application.mta_context == "ViaWebUI": url = self.context["object"].application.hostname return url in self.context[ "object"].application.web_ui.widgetastic_browser.url @property def is_displayed(self): return (self.username.is_displayed and self.login_button.is_displayed ) or (self.validate_url() and self.header.is_displayed) def login(self, user, password): self.fill({"username": user, "password": password}) self.login_button.click()
class PageCard(CardForCardGroup): dropdown = Dropdown() def delete_action(self): self.dropdown.item_select("Delete") checked = CardCheckBox() header_text = Text(locator="./div[@class='pf-c-card__title']")
class NewHostDetailsView(BaseLoggedInView): breadcrumb = BreadCrumb('OUIA-Generated-Breadcrumb-1') @property def is_displayed(self): breadcrumb_loaded = self.browser.wait_for_element( self.Overview.RecentJobsCard.is_table_loaded, exception=False) return breadcrumb_loaded and self.breadcrumb.locations[0] == 'Hosts' edit = Button('OUIA-Generated-Button-secondary-1') dropdown = Dropdown(locator='//button[@id="hostdetails-kebab"]/..') @View.nested class Overview(Tab): ROOT = './/div[contains(@class, "host-details-tab-item")]' @View.nested class DetailsCard(Card): ROOT = '(.//article[contains(@class, "pf-c-card")])[1]' details = HostDetailsCard() @View.nested class HostStatusCard(Card): ROOT = '(//article[contains(@class, "pf-c-card")])[2]' status = Text( './/h4[contains(@data-ouia-component-id, "OUIA-Generated-Title")]' ) status_success = Text('.//span[@class="status-success"]') status_warning = Text('.//span[@class="status-warning"]') status_error = Text('.//span[@class="status-error"]') status_disabled = Text('.//span[@class="disabled"]') @View.nested class RecentJobsCard(Card): ROOT = '(//article[contains(@class, "pf-c-card")])[5]' is_table_loaded = './/ul[@aria-label="recent-jobs-table"]' @View.nested class Content(Tab): pass @View.nested class Traces(Tab): enable_traces = Button('OUIA-Generated-Button-primary-1') @View.nested class RepositorySets(Tab): pass @View.nested class Ansible(Tab): pass @View.nested class Insights(Tab): pass
class AllProjectView(BaseLoggedInPage): """This view represent Project All View""" title = Text(".//div[contains(@class, 'pf-c-content')]/h1") search = Input(locator=".//input[@aria-label='Filter by name']") sort = SortSelector("class", "btn btn-default dropdown-toggle") table_loading = './/div[contains(@class, "pf-c-skeleton")]' ACTIONS_INDEX = 4 table = PatternflyTable( ".//table[contains(@class, 'pf-c-table pf-m-grid-md')]", column_widgets={ "Name": Text(locator=".//a"), "Applications": Text(locator=".//td[@data-label='Applications']"), "Status": Text(locator=".//td[@data-label='Status']"), "Description": Text(locator=".//td[@data-label='Description']"), ACTIONS_INDEX: Dropdown(), }, ) create_project = Button("Create project") @View.nested class no_matches(View): # noqa """After search if no match found""" text = Text(".//div[contains(@class, 'pf-c-empty-state__body')]") def clear_search(self): """Clear search""" if self.search.value: self.search.fill("") @property def all_projects(self): """Returns list of all project rows""" return [row for row in self.table] @property def is_displayed(self): return self.is_empty or ( self.create_project.is_displayed and self.title.text == "Projects" and self.table.is_displayed and self.validate_url() ) def select_project(self, name): for row in self.table: if row.name.text == name: row["Name"].widget.click() def table_loaded(self): return wait_for( lambda: not self.browser.is_displayed(self.table_loading), delay=10, timeout=120 )
class PageCard( CardForCardGroup, ): def __init__(self, parent, locator=None, logger=None, **kwargs): super().__init__(parent, locator=locator, logger=logger, **kwargs) # workaround for overlapping bottom paginator # TODO fix it in widgetastic.core self.browser.execute_script( "arguments[0].scrollIntoView({block: 'center'});", self.__element__()) dropdown = Dropdown() def delete_action(self): self.dropdown.item_select("Delete") checked = CardCheckBox() header_text = Text(locator="./div[@class='pf-c-card__title']")
class SystemLabelsView(BaseLoggedInPage): """This view represents System labels tab page""" paginator = Pagination( locator='.//div[contains(@class, "pf-c-pagination")]') table = Table( locator='.//table[contains(@aria-label, "Table")]', column_widgets={ "Provider ID": Button(locator='.//th[@data-label="Provider ID"]/button'), 2: Dropdown(), }, ) search = Input(locator='.//input[@aria-label="Filter by provider ID"]') @property def is_displayed(self): return self.table.is_displayed and self.search.is_displayed
class CustomLabelsView(BaseLoggedInPage): """This view represents Custom labels tab page""" paginator = Pagination( locator='.//div[contains(@class, "pf-c-pagination")]') add_label_button = Button("Add label") search = Input(locator=".//input[@aria-label='Filter by short path']") ACTIONS_INDEX = 2 table = Table( locator='.//table[contains(@aria-label, "Table")]', column_widgets={ "Short path": Button(locator='.//th[@data-label="Short path"]/button'), ACTIONS_INDEX: Dropdown(), }, ) @property def is_displayed(self): return self.add_label_button.is_displayed and self.table.is_displayed
class BaseLoggedInPage(View): """This is base view for MTA""" header = Text(locator=".//img[@alt='brand']") navigation = MTANavigation(locator='//ul[@class="pf-c-nav__list"]') logout_button = Dropdown(text="mta") setting = DropdownMenu( locator= ".//li[contains(@class, 'dropdown') and .//span[@class='pficon pficon-user']]" ) help = Button(id="aboutButton") # only if no project available blank_state = View.nested(BlankStateView) def validate_url(self): """The logged in Page in both web console and operator are same so added a url check to differentiate in the view""" if self.context["object"].application.mta_context == "ViaOperatorUI": url = self.context["object"].application.ocphostname elif self.context["object"].application.mta_context == "ViaSecure": url = self.context["object"].application.ocpsecurehostname elif self.context["object"].application.mta_context == "ViaWebUI": url = self.context["object"].application.hostname return url in self.context[ "object"].application.web_ui.widgetastic_browser.url @property def is_empty(self): """Check project is available or not; blank state""" return self.blank_state.is_displayed and self.validate_url() @property def is_displayed(self): return self.header.is_displayed and self.help.is_displayed and self.validate_url( ) def logout(self): self.view.logout_button.item_select("Logout")
class AnalysisResultsView(BaseLoggedInPage): run_analysis_button = Button("Run analysis") title = Text(locator=".//div/h1[normalize-space(.)='Analysis results']") search = Input( locator=".//input[@aria-label='Filter by analysis id or status']") analysis_results = AnalysisResults() confirm_delete = Button("Yes") cancel_delete = Button("No") sort_analysis = Text( locator=".//th[contains(normalize-space(.), 'Analysis')]//button") table = Table( locator='.//table[contains(@aria-label, "Table")]', column_widgets={ "Analysis": Text(locator=".//a"), 5: Dropdown() }, ) @property def is_displayed(self): return self.run_analysis_button.is_displayed and self.title.is_displayed def clear_search(self): """Clear search""" self.search.fill("") @ParametrizedView.nested class analysis_row(ParametrizedView): # noqa PARAMETERS = ("row", ) analysis_number = Text(ParametrizedLocator(".//tr[{row}]/td[1]/a")) delete_analysis = Text( ParametrizedLocator( ".//tr[{row}]//button[@class='pf-c-button pf-m-link']")) @property def is_displayed(self): return self.analysis_number.is_displayed
class TestView(View): ROOT = "(.//div[@id='ws-react-c-dropdown-basic'])[1]" dropdown_txt_locator = Dropdown("Dropdown") dropdown_custom_locator = Dropdown( locator=".//div[contains(@class, 'pf-c-dropdown')]") dropdown_default_locator = Dropdown()
class TestView(View): dropdown = Dropdown("Dropdown") kebab = Kebab(".//h1[normalize-space(.)='Kebab']/../" "/div[contains(@class, 'pf-c-dropdown')]")