class KeyPairEntities(View): title = Text('//div[@id="main-content"]//h1') table = Table("//div[@id='list_grid']//table") search = View.nested(Search) # element attributes changed from id to class in upstream-fine+, capture both with locator flash = FlashMessages('.//div[@id="flash_msg_div"]' '/div[@id="flash_text_div" or contains(@class, "flash_text_div")]')
class ServerEntitiesView(BaseEntitiesView): """Entities on the main list page""" title = Text(TITLE_LOCATOR) table = Table(LIST_TABLE_LOCATOR) search = View.nested(Search) # element attributes changed from id to class in upstream-fine+, capture both with locator flash = FlashMessages(FLASH_MESSAGE_LOCATOR)
class ServicesCatalogView(BaseLoggedInPage): def in_explorer(self): return ( self.logged_in_as_current_user and self.navigation.currently_selected == ['Services', 'Catalogs']) @property def is_displayed(self): return self.in_explorer and self.configuration.is_displayed and not self.catalogs.is_dimmed @View.nested class service_catalogs(Accordion): # noqa ACCORDION_NAME = "Service Catalogs" tree = ManageIQTree() @View.nested class catalog_items(Accordion): # noqa ACCORDION_NAME = "Catalog Items" tree = ManageIQTree() @View.nested class orchestration_templates(Accordion): # noqa ACCORDION_NAME = "Orchestration Templates" tree = ManageIQTree() @View.nested class catalogs(Accordion): # noqa tree = ManageIQTree() configuration = Dropdown('Configuration') policy = Dropdown('Policy') flash = FlashMessages(".//div[@id='flash_msg_div']/div")
class ContainerObjectDetailsBaseView(BaseLoggedInPage, LoggingableView): title = Text('//div[@id="main-content"]//h1') breadcrumb = BreadCrumb(locator='//ol[@class="breadcrumb"]') toolbar = View.nested(ProviderDetailsToolBar) flash = FlashMessages( './/div[@id="flash_msg_div"]/div[@id="flash_text_div" or ' 'contains(@class, "flash_text_div")]') entities = View.nested(ContainerObjectDetailsEntities) @View.nested class sidebar(ProviderSideBar): # noqa @View.nested class properties(Accordion): # noqa tree = ManageIQTree() @View.nested class relationships(Accordion): # noqa tree = ManageIQTree() @property def is_displayed(self): return (self.title.is_displayed and self.breadcrumb.is_displayed and self.breadcrumb.active_location == '{} (Summary)'.format( self.context['object'].name))
class RedHatUpdatesView(RegionView): title = Text('//div[@id="main-content"]//h3[1]') edit_registration = Button('Edit Registration') updates_table = Table("//div[@id='form_div']/table") flash = FlashMessages( './/div[@id="flash_msg_div"]/div[@id="flash_text_div" or ' 'contains(@class, "flash_text_div")]')
class SchedulesFormCommon(CloudIntelReportsView): flash = FlashMessages( './/div[@id="flash_msg_div"]/div[@id="flash_text_div" or ' 'contains(@class, "flash_text_div")] | ' './/div[starts-with(@class, "flash_text_div") or @id="flash_text_div"]' ) # Basic Information title = Text("#explorer_title_text") name = TextInput(name="name") description = TextInput(name="description") active = Checkbox("enabled") # Report Selection filter1 = BootstrapSelectRetry("filter_typ") filter2 = BootstrapSelectRetry("subfilter_typ") filter3 = BootstrapSelectRetry("repfilter_typ") # Timer run = BootstrapSelect("timer_typ") time_zone = BootstrapSelect("time_zone") starting_date = Calendar("miq_date_1") hour = BootstrapSelect("start_hour") minute = BootstrapSelect("start_min") # Email emails_send = Checkbox("send_email_cb") emails = AlertEmail() send_if_empty = Checkbox("send_if_empty") send_txt = Checkbox("send_txt") send_csv = Checkbox("send_csv") send_pdf = Checkbox("send_pdf") # Buttons cancel_button = Button("Cancel")
class LoginPage(View): flash = FlashMessages('div#flash_text_div') username = Input(id='inputUsername') password = Input(id='inputPassword') login = Button('Log In') def submit_login(self, method='click_on_login'): if method == 'click_on_login': self.login.click() elif method == 'press_enter_after_password': self.browser.send_keys(Keys.ENTER, self.password) else: raise ValueError('Unknown method {}'.format(method)) if self.flash.is_displayed: self.flash.assert_no_error() def log_in(self, user, method='click_on_login'): self.fill({ 'username': user.credential.principal, 'password': user.credential.secret, }) self.submit_login(method) logged_in_view = self.browser.create_view(SSUIBaseLoggedInPage) if logged_in_view.logged_in: if user.name is None: name = logged_in_view.current_fullname self.logger.info( 'setting the appliance.user.name to %r because it was not specified', name) user.name = name self.extra.appliance.user = user
class ProviderAddView(BaseLoggedInPage): """ represents Provider Add View """ title = Text('//div[@id="main-content"]//h1') name = Input('name') prov_type = BootstrapSelect(id='emstype') keystone_v3_domain_id = Input('keystone_v3_domain_id') # OpenStack only zone = Input('zone') flash = FlashMessages( './/div[@id="flash_msg_div"]/div[@id="flash_text_div" or ' 'contains(@class, "flash_text_div")]') add = Button('Add') cancel = Button('Cancel') @View.nested class endpoints(View): # NOQA # this is switchable view that gets replaced with concrete view. # it gets changed according to currently chosen provider type # look at cfme.common.provider.BaseProvider.create() method pass @property def is_displayed(self): return self.logged_in_as_current_user
class PXEServerForm(View): title = Text('//div[@id="main-content"]//h1') flash = FlashMessages( './/div[@id="flash_msg_div"]/div[@id="flash_text_div" or ' 'contains(@class, "flash_text_div")]') # common fields name = Input(id='name') depot_type = BootstrapSelect(id='log_protocol') access_url = Input(id='access_url') pxe_dir = Input(id='pxe_directory') windows_images_dir = Input(id='windows_images_directory') customization_dir = Input(id='customization_directory') filename = Input(id='pxemenu_0') uri = Input(id='uri') # both NFS and Samba # Samba only username = Input(id='log_userid') password = Input(id='log_password') confirm_password = Input(id='log_verify') validate = Button('Validate the credentials by logging into the Server') @property def is_displayed(self): return False
class DatastoreDetailsView(BaseLoggedInPage): """ represents Datastore Details page """ title = Text('//div[@id="main-content"]//h1') flash = FlashMessages( './/div[@id="flash_msg_div"]/div[@id="flash_text_div" or ' 'contains(@class, "flash_text_div")]') toolbar = View.nested(DatastoreToolBar) sidebar = View.nested(DatastoreSideBar) @View.nested class contents(View): # noqa """ represents Details page when it is switched to Summary aka Tables view """ properties = SummaryTable(title="Properties") registered_vms = SummaryTable(title="Information for Registered VMs") relationships = SummaryTable(title="Relationships") content = SummaryTable(title="Content") smart_management = SummaryTable(title="Smart Management") @property def is_displayed(self): return (super(BaseLoggedInPage, self).is_displayed and self.navigation.currently_selected == ['Compute', 'Infrastructure', 'Datastores'] and self.title.text == 'Datastore "{name}"'.format( name=self.context['object'].name))
class AssignmentsView(ChargebackView): title = Text("#explorer_title_text") flash = FlashMessages( './/div[@id="flash_msg_div"]/div[@id="flash_text_div" or ' 'contains(@class, "flash_text_div")]') save_button = Button("Save") reset_button = Button("Reset") @property def is_displayed(self): return (self.in_chargeback and self.title.text == '"{}" Rate Assignments'.format( self.context["object"].description) and self.assignments.is_opened and self.rates.tree.currently_selected == ["{} Rate Assignments", self.context["object"].description]) assign_to = BootstrapSelect(id="cbshow_typ") tag_category = BootstrapSelect(id='cbtag_cat') docker_labels = BootstrapSelect(id='cblabel_key') _table_locator = '//h3[contains(text(),"Selections")]/following-sibling::table' _table_widget_locator = './/div[contains(@class, "bootstrap-select")]' selections = Table( locator=_table_locator, column_widgets={ 'Rate': BootstrapSelectByLocator(locator=_table_widget_locator) }, assoc_column=0)
class ConfigurationView(BaseLoggedInPage): flash = FlashMessages('.//div[starts-with(@id, "flash_text_div")]') title = Text('#explorer_title_text') @View.nested class accordions(View): # noqa @View.nested class settings(Accordion): # noqa ACCORDION_NAME = "Settings" tree = ManageIQTree() @View.nested class accesscontrol(Accordion): # noqa ACCORDION_NAME = "Access Control" tree = ManageIQTree() @View.nested class diagnostics(Accordion): # noqa ACCORDION_NAME = "Diagnostics" tree = ManageIQTree() @View.nested class database(Accordion): # noqa ACCORDION_NAME = "Database" tree = ManageIQTree() @property def is_displayed(self): # TODO: We will need a better ID of this location when we have user permissions in effect return (self.accordions.settings.is_displayed and self.accordions.accesscontrol.is_displayed and self.accordions.diagnostics.is_displayed and self.accordions.database.is_displayed)
class SchedulesFormCommon(CloudIntelReportsView): flash = FlashMessages('.//div[@id="flash_msg_div"]') # Basic Information title = Text("#explorer_title_text") name = TextInput(name="name") description = TextInput(name="description") active = Checkbox("enabled") # Report Selection filter1 = BootstrapSelectRetry("filter_typ") filter2 = BootstrapSelectRetry("subfilter_typ") filter3 = BootstrapSelectRetry("repfilter_typ") # Timer run = BootstrapSelect("timer_typ") # Adding timer for hour, day, week, and zone because there is no single element # for the timer_interval. timer_hour = BootstrapSelect("timer_hours") timer_day = BootstrapSelect("timer_days") timer_month = BootstrapSelect("timer_months") timer_week = BootstrapSelect("timer_weeks") time_zone = BootstrapSelect("time_zone") starting_date = Calendar("miq_date_1") hour = BootstrapSelect("start_hour") minute = BootstrapSelect("start_min") # Email emails_send = Checkbox("send_email_cb") from_email = TextInput(name="from") emails = AlertEmail() send_if_empty = Checkbox("send_if_empty") send_txt = Checkbox("send_txt") send_csv = Checkbox("send_csv") send_pdf = Checkbox("send_pdf") # Buttons cancel_button = Button("Cancel")
class ServerAuthenticationView(View): """ Server Authentication View.""" title = Text("//div[@id='settings_authentication']/h3[1]") # Local Flash widget for validation since class nested under a class inheriting BaseLoggedInPage flash = FlashMessages('.//div[@id="flash_msg_div"]') hours_timeout = BootstrapSelect(id='session_timeout_hours') minutes_timeout = BootstrapSelect(id='session_timeout_mins') # TODO new button widget to handle buttons_on buttons_off divs save = Button(title='Save Changes') # in buttons_on div reset = Button(title='Reset Changes') # in buttons_on div @View.nested class form(View): # noqa auth_mode = BootstrapSelect(id='authentication_mode') auth_settings = ConditionalSwitchableView(reference='auth_mode') auth_settings.register('Database', default=True, widget=DatabaseAuthenticationView) auth_settings.register('LDAP', widget=LdapAuthenticationView) auth_settings.register('LDAPS', widget=LdapsAuthenticationView) auth_settings.register('Amazon', widget=AmazonAuthenticationView) auth_settings.register('External (httpd)', widget=ExternalAuthenticationView) @property def is_displayed(self): """should be paired with a ServerView.in_server_settings in a nav.am_i_here""" return (self.form.auth_mode.is_displayed and self.title.text == 'Authentication')
class StackOutputsEntities(View): """The entities of the resources page""" breadcrumb = BreadCrumb() title = Text('//div[@id="main-content"]//h1') outputs = Table('//div[@id="list_grid"]//table') # element attributes changed from id to class in upstream-fine+, capture both with locator flash = FlashMessages('.//div[@id="flash_msg_div"]' '/div[@id="flash_text_div" or contains(@class, "flash_text_div")]')
class KeyPairDetailsEntities(View): breadcrumb = BreadCrumb() title = Text('//div[@id="main-content"]//h1') flash = FlashMessages('.//div[@id="flash_msg_div"]' '/div[@id="flash_text_div" or contains(@class, "flash_text_div")]') properties = SummaryTable(title='Properties') relationships = SummaryTable(title='Relationships') smart_management = SummaryTable(title='Smart Management')
class ServerGroupDetailsEntities(View): """Entities on the details page""" breadcrumb = BreadCrumb() title = Text(TITLE_LOCATOR) properties = SummaryTable(title='Properties') relationships = SummaryTable(title='Relationships') smart_management = SummaryTable(title='Smart Management') flash = FlashMessages(FLASH_MESSAGE_LOCATOR)
class StackEntities(View): """The entties on the main list page""" title = Text('//div[@id="main-content"]//h1') table = Table("//div[@id='gtl_div']//table") search = View.nested(Search) # element attributes changed from id to class in upstream-fine+, capture both with locator flash = FlashMessages('.//div[@id="flash_msg_div"]' '/div[@id="flash_text_div" or contains(@class, "flash_text_div")]')
class ResourcePoolEntities(View): """Entities on the main list page""" title = Text('//div[@id="main-content"]//h1') table = Table(".//div[@id='list_grid']//table|.//div[@id='miq-gtl-view']//table") search = View.nested(Search) # element attributes changed from id to class in upstream-fine+, capture both with locator flash = FlashMessages('.//div[@id="flash_msg_div"]' '/div[@id="flash_text_div" or contains(@class, "flash_text_div")]')
class BaseLoggedInPage(View): """This page should be subclassed by any page that models any other page that is available as logged in. """ CSRF_TOKEN = '//meta[@name="csrf-token"]' flash = FlashMessages( './/div[starts-with(@class, "flash_text_div") or @id="flash_text_div"]' ) help = NavDropdown( './/li[./a[@id="dropdownMenu1"]]|.//li[./a[@id="help-menu"]]') settings = NavDropdown('.//li[./a[@id="dropdownMenu2"]]') navigation = VerticalNavigation('#maintab') @property def is_displayed(self): return self.logged_in_as_current_user def logged_in_as_user(self, user): if self.logged_out: return False return user.name == self.current_fullname @property def logged_in_as_current_user(self): return self.logged_in_as_user(self.extra.appliance.user) @property def current_username(self): try: return self.extra.appliance.user.principal except AttributeError: return None @property def current_fullname(self): return self.settings.text.strip().split('|', 1)[0].strip() @property def logged_in(self): return self.settings.is_displayed @property def logged_out(self): return not self.logged_in def logout(self): self.settings.select_item('Logout') self.browser.handle_alert(wait=None) self.extra.appliance.user = None @property def csrf_token(self): return self.browser.get_attribute('csrf-token', self.CSRF_TOKEN) @csrf_token.setter def csrf_token(self, value): self.browser.set_attribute('csrf-token', value, self.CSRF_TOKEN)
class AddDeploymentView(DeploymentView): """The "Add" view -- new deployments""" @property def is_displayed(self): """ This view is opened as a widget box after clicking on toolbar operation """ return False form = View.nested(AddDeploymentForm) flash = FlashMessages(FLASH_MESSAGE_LOCATOR)
class PXEDatastoreForm(View): title = Text('//div[@id="main-content"]//h1') flash = FlashMessages('.//div[@id="flash_msg_div"]/div[@id="flash_text_div" or ' 'contains(@class, "flash_text_div")]') provider = BootstrapSelect(id='ems_id') @property def is_displayed(self): return False
class InstanceEntities(View): title = Text( '//div[@id="main-content"]//h1//span[@id="explorer_title_text"]') adv_search_clear = Text( '//div[@id="main-content"]//h1//span[@id="clear_search"]/a') flash = FlashMessages( './/div[@id="flash_msg_div"]' '/div[@id="flash_text_div" or contains(@class, "flash_text_div")]') search = View.nested(Search) table = Table("//div[@id='list_grid']//table")
class PXESystemImageTypeForm(View): title = Text('//div[@id="main-content"]//h1') flash = FlashMessages('.//div[@id="flash_msg_div"]/div[@id="flash_text_div" or ' 'contains(@class, "flash_text_div")]') name = Input(id='name') type = BootstrapSelect(id='provision_type') @property def is_displayed(self): return False
class TenantDetailsEntities(View): """The entities on the details page""" breadcrumb = BreadCrumb() title = Text('//div[@id="main-content"]//h1') relationships = SummaryTable(title='Relationships') quotas = SummaryTable(title='Quotas') smart_management = SummaryTable(title='Smart Management') # element attributes changed from id to class in upstream-fine+, capture both with locator flash = FlashMessages('.//div[@id="flash_msg_div"]' '/div[@id="flash_text_div" or contains(@class, "flash_text_div")]')
class ConfigManagementAddEntities(View): """The entities on the add page""" title = Text('//div[@id="main-content"]//h1') form = View.nested(ConfigManagementAddForm) add = Button('Add') cancel = Button('Cancel') # element attributes changed from id to class in upstream-fine+, capture both with locator flash = FlashMessages('.//div[@id="flash_msg_div"]' '/div[@id="flash_text_div" or contains(@class, "flash_text_div")]')
class RepositoryBaseView(BaseLoggedInPage): flash = FlashMessages('.//div[starts-with(@class, "flash_text_div") or @id="flash_text_div"]') title = Text(locator='.//div[@id="main-content"]//h1') @property def in_ansible_repositories(self): return ( self.logged_in_as_current_user and self.navigation.currently_selected == ["Automation", "Ansible", "Repositories"] )
class ProviderDetailsView(BaseLoggedInPage): """ main Details page """ title = Text('//div[@id="main-content"]//h1') breadcrumb = BreadCrumb(locator='//ol[@class="breadcrumb"]') flash = FlashMessages( './/div[@id="flash_msg_div"]/div[@id="flash_text_div" or ' 'contains(@class, "flash_text_div")]') toolbar = View.nested(ProviderDetailsToolBar) @View.nested class contents(View): # NOQA # this is switchable view that gets replaced with concrete view. # it gets changed according to currently chosen view type every time # when it is accessed # it is provided provided by __getattribute__ pass def __getattribute__(self, item): # todo: to replace this code with switchable views asap if item == 'contents': if self.context['object'].appliance.version >= '5.7': view_type = self.toolbar.view_selector.selected # cloud provider details view doesn't have such switch, BZ(1460772) if view_type == 'Summary View': return ProviderDetailsSummaryView(parent=self) elif view_type == 'Dashboard View': return ProviderDetailsDashboardView(parent=self) else: raise Exception( 'The content view type "{v}" for provider "{p}" doesnt ' 'exist'.format(v=view_type, p=self.context['object'].name)) else: return ProviderDetailsSummaryView( parent=self) # 5.6 has only only Summary view else: return super(ProviderDetailsView, self).__getattribute__(item) @property def is_displayed(self): if (not self.toolbar.view_selector.is_displayed or self.toolbar.view_selector.selected == 'Summary View'): subtitle = 'Summary' else: subtitle = 'Dashboard' title = '{name} ({subtitle})'.format(name=self.context['object'].name, subtitle=subtitle) return (self.logged_in_as_current_user and self.breadcrumb.is_displayed and self.breadcrumb.active_location == title)
class TasksView(BaseLoggedInPage): flash = FlashMessages('.//div[starts-with(@id, "flash_text_div")]') # Toolbar delete = Dropdown( 'Delete Tasks') # dropdown just has icon, use element title reload = Button(title='Reload the current display') @View.nested class tabs(View): # noqa # Extra Toolbar # Only on 'All' type tabs, but for access it doesn't make sense to access the tab for a # toolbar button cancel = Button(title='Cancel the selected task') # Form Buttons apply = Button('Apply') reset = Button('Reset') default = Button('Default') # Filters zone = BootstrapSelect(id='chosen_zone') period = BootstrapSelect(id='time_period') user = BootstrapSelect(id='user_choice') # This checkbox search_root captures all the filter options # It will break for status if/when there is second checkbox selection field added # It's the lowest level div with an id that captures the status checkboxes status = CheckboxSelect(search_root='tasks_options_div') state = BootstrapSelect(id='state_choice') @View.nested class mytasks(Tab): # noqa TAB_NAME = "My VM and Container Analysis Tasks" table = Table(table_loc) @View.nested class myothertasks(Tab): # noqa TAB_NAME = "My Other UI Tasks" table = Table(table_loc) @View.nested class alltasks(Tab): # noqa TAB_NAME = "All VM and Container Analysis Tasks" table = Table(table_loc) @View.nested class allothertasks(Tab): # noqa TAB_NAME = "All Other Tasks" table = Table(table_loc) @property def is_displayed(self): return (self.tabs.mytasks.is_displayed and self.tabs.myothertasks.is_displayed and self.tabs.alltasks.is_displayed and self.tabs.allothertasks.is_displayed)
class CredentialsBaseView(BaseLoggedInPage): flash = FlashMessages( './/div[starts-with(@class, "flash_text_div") or @id="flash_text_div"]' ) title = Text(locator=".//div[@id='main-content']//h1") @property def in_ansible_credentials(self): return (self.logged_in_as_current_user and self.navigation.currently_selected == ["Automation", "Ansible", "Credentials"])