Input("chkbx_submit")), ('cancel_button', Input("chkbx_cancel"))]) tab_form = Form( fields=[('tab_label', Input("tab_label")), ('tab_desc', Input("tab_description"))]) box_form = Form( fields=[('box_label', Input("group_label")), ('box_desc', Input("group_description"))]) element_form = Form(fields=[ ('ele_label', Input("field_label")), ('ele_name', Input("field_name")), ('ele_desc', Input("field_description")), ('choose_type', { version.LOWEST: Select("//select[@id='field_typ']"), "5.5": AngularSelect("field_typ") }), ('default_text_box', Input("field_default_value")), ('field_required', Input("field_required")), ('field_past_dates', Input("field_past_dates")), ('field_entry_point', Input("field_entry_point")), ('field_show_refresh_button', Input("field_show_refresh_button")), ('entry_value', Input("entry[value]")), ('entry_description', Input("entry[description]")), ('add_entry_button', Input("accept")), # This one too? vvv I could not find it in the form ('field_category', Select("//select[@id='field_category']")), ('text_area', { version.LOWEST: Input("field_default_value"), "5.5": AngularSelect("field_default_value")
fill, flash, form_buttons, Input, Table, UpDownSelect, CFMECheckbox, BootstrapTreeview) from cfme.web_ui.form_buttons import change_stored_password from utils import version, deferred_verpick from utils.appliance import Navigatable from utils.appliance.implementations.ui import navigator, CFMENavigateStep, navigate_to from utils.log import logger from utils.pretty import Pretty from utils.update import Updateable tb_select = partial(tb.select, "Configuration") pol_btn = partial(tb.select, "Policy") edit_tags_form = Form(fields=[( "select_tag", Select("select#tag_cat")), ("select_value", Select("select#tag_add"))]) tag_table = Table("//div[@id='assignments_div']//table") users_table = Table("//div[@id='records_div']//table") group_order_selector = UpDownSelect("select#seq_fields", "//img[@alt='Move selected fields up']", "//img[@alt='Move selected fields down']") def simple_user(userid, password): creds = Credential(principal=userid, secret=password) return User(name=userid, credential=creds) class User(Updateable, Pretty, Navigatable):
def select(self): return Select(self._loc)
class Timeprofile(Updateable): timeprofile_form = Form(fields=[ ("description", Input("description")), ("scope", Select("select#profile_type")), ("timezone", Select("select#profile_tz")), ("days", Input("all_days")), ("hours", Input("all_hours")), ]) save_button = form_buttons.FormButton("Add this Time Profile") def __init__(self, description=None, scope=None, days=None, hours=None, timezone=None): self.description = description self.scope = scope self.days = days self.hours = hours self.timezone = timezone def create(self): sel.force_navigate('timeprofile_new') fill(self.timeprofile_form, { 'description': self.description, 'scope': self.scope, 'days': self.days, 'hours': self.hours, 'timezone': self.timezone, }, action=self.save_button) flash.assert_success_message('Time Profile "{}" was added'.format( self.description)) def update(self, updates): sel.force_navigate("timeprofile_edit", context={"timeprofile": self}) fill(self.timeprofile_form, { 'description': updates.get('description'), 'scope': updates.get('scope'), 'timezone': updates.get('timezone') }, action=form_buttons.save) flash.assert_success_message('Time Profile "{}" was saved'.format( updates.get('description', self.description))) def copy(self): sel.force_navigate("my_settings_time_profiles") row = timeprofile_table.find_row_by_cells( {'description': self.description}) sel.check(sel.element(".//input[@type='checkbox']", root=row[0])) cfg_btn('Copy selected Time Profile') new_timeprofile = Timeprofile(description=self.description + "copy", scope=self.scope) fill(self.timeprofile_form, { 'description': new_timeprofile.description, 'scope': new_timeprofile.scope }, action=self.save_button) flash.assert_success_message('Time Profile "{}" was added'.format( new_timeprofile.description)) return new_timeprofile def delete(self): sel.force_navigate("my_settings_time_profiles") row = timeprofile_table.find_row_by_cells( {'description': self.description}) sel.check(sel.element(".//input[@type='checkbox']", root=row[0])) cfg_btn('Delete selected Time Profiles', invokes_alert=True) sel.handle_alert() flash.assert_success_message( 'Time Profile "{}": Delete successful'.format(self.description))
), ('cancel_button', form_buttons.FormButton("Cancel"))]) jdbc_driver_form = Form( fields=[("file_select", FileInput("jdbc_driver[file]") ), ("jdbc_driver_name", Input("jdbc_driver_name_input") ), ("jdbc_module_name", Input("jdbc_module_name_input") ), ("jdbc_driver_class", Input("jdbc_driver_class_input") ), ("major_version", Input("major_version_input") ), ("minor_version", Input("minor_version_input")), ('deploy_button', form_buttons.FormButton("Deploy", ng_click="addJdbcDriver()") ), ('cancel_button', form_buttons.FormButton("Cancel"))]) datasource_form = Form(fields=[ ("ds_type", Select("//select[@id='chooose_datasource_input']") ), ("xa_ds", CFMECheckbox("xa_ds_cb")), ( "ds_name", Input("ds_name_input")), ("jndi_name", Input("jndi_name_input")), ("driver_name", Input("jdbc_ds_driver_name_input") ), ("driver_module_name", Input("jdbc_modoule_name_input")), ("driver_class", Input("jdbc_ds_driver_input")), ("existing_driver", Select("//select[@id='existing_jdbc_driver_input']")), ("ds_url", Input("connection_url_input")), ( "username", Input("user_name_input")), ("password", Input("password_input")), ("sec_domain", Input("security_domain_input", use_id=True)), ('next0_button', form_buttons.FormButton('Next', ng_click="addDatasourceChooseNext()")),
def __init__(self, unselected, selected, to_unselected, to_selected, remove_all=None): self._unselected = Select(unselected, multi=True) self._selected = Select(selected, multi=True) self._to_unselected = to_unselected self._to_selected = to_selected self._remove_all = remove_all
def select_by_name(self, name): return self.select_from_row(self.row_by_name(name)) @fill.method((AssignFormTable, Mapping)) def _fill_assignform_dict(form, d): d = copy(d) # Mutable for name, value in d.iteritems(): if value is None: value = "<Nothing>" select = form.select_by_name(name) sel.select(select, value) assign_form = Form(fields=[ ("assign_to", Select("select#cbshow_typ")), # Enterprise ("enterprise", Select("select#enterprise__1")), # Simple shotcut, might explode one time # Tagged DS ("tag_category", Select("select#cbtag_cat")), # Common - selection table ("selections", AssignFormTable({ LOWEST: ("//div[@id='cb_assignment_div']/fieldset/table[contains(@class, 'style1')]" "/tbody/tr/td/table"), "5.4": "//div[@id='cb_assignment_div']/table[contains(@class, 'table')]", })), ('save_button', form_buttons.save)
class BaseVM(Pretty, Updateable, PolicyProfileAssignable, WidgetasticTaggable, SummaryMixin, Navigatable): """Base VM and Template class that holds the largest common functionality between VMs, instances, templates and images. In order to inherit these, you have to implement the ``on_details`` method. """ pretty_attrs = ['name', 'provider', 'template_name'] # Forms edit_form = Form(fields=[ ('custom_ident', Input("custom_1")), ('description_tarea', "//textarea[@id='description']"), ('parent_sel', { version.LOWEST: Select("//select[@name='chosen_parent']"), "5.5": AngularSelect("chosen_parent") }), ('child_sel', Select("//select[@id='kids_chosen']", multi=True)), ('vm_sel', Select("//select[@id='choices_chosen']", multi=True)), ('add_btn', "//img[@alt='Move selected VMs to left']"), ('remove_btn', "//img[@alt='Move selected VMs to right']"), ('remove_all_btn', "//img[@alt='Move all VMs to right']"), ]) ### # Factory class methods # @classmethod def factory(cls, vm_name, provider, template_name=None, template=False): """Factory class method that determines the correct subclass for given provider. For reference how does that work, refer to the entrypoints in the setup.py Args: vm_name: Name of the VM/Instance as it appears in the UI provider: The provider object (not the string!) template_name: Source template name. Useful when the VM/Instance does not exist and you want to create it. template: Whether the generated object class should be VM/Instance or a template class. """ try: return all_types(template)[provider.type](vm_name, provider, template_name) except KeyError: # Matching via provider type failed. Maybe we have some generic classes for infra/cloud? try: return all_types(template)[provider.category](vm_name, provider, template_name) except KeyError: raise UnknownProviderType( 'Unknown type of provider CRUD object: {}'.format( provider.__class__.__name__)) ### # To be set or implemented # ALL_LIST_LOCATION = None TO_OPEN_EDIT = None # Name of the item in Configuration that puts you in the form QUADICON_TYPE = "vm" # Titles of the delete buttons in configuration REMOVE_SELECTED = { '5.6': 'Remove selected items', '5.6.2.2': 'Remove selected items from the VMDB', '5.7': 'Remove selected items' } REMOVE_SINGLE = { '5.6': 'Remove Virtual Machine', '5.6.2.2': 'Remove from the VMDB', '5.7': 'Remove Virtual Machine' } RETIRE_DATE_FMT = { version.LOWEST: parsetime.american_date_only_format, '5.7': parsetime.american_minutes_with_utc } _param_name = ParamClassName('name') ### # Shared behaviour # def __init__(self, name, provider, template_name=None, appliance=None): super(BaseVM, self).__init__() Navigatable.__init__(self, appliance=appliance) if type(self) in {BaseVM, VM, Template}: raise NotImplementedError('This class cannot be instantiated.') self.name = name self.provider = provider self.template_name = template_name ### # Properties # @property def is_vm(self): return not isinstance(self, _TemplateMixin) @property def quadicon_type(self): return self.QUADICON_TYPE @property def paged_table(self): return PagedTable('//table') ### # Methods # def check_compliance(self, timeout=240): """Initiates compliance check and waits for it to finish. TODO This should be refactored as it's done `Host.check_compliance`. It shouldn't return anything. `compliant` property should use `compliance_status`. """ original_state = self.compliance_status cfg_btn("Refresh Relationships and Power States", invokes_alert=True) sel.handle_alert() flash.assert_no_errors() pol_btn("Check Compliance of Last Known Configuration", invokes_alert=True) sel.handle_alert() flash.assert_no_errors() wait_for(lambda: self.compliance_status != original_state, num_sec=timeout, delay=5, message="compliance of {} checked".format(self.name)) return self.compliant @property def compliance_status(self): """Returns the title of the compliance infoblock. The title contains datetime so it can be compared. Returns: :py:class:`NoneType` if no title is present (no compliance checks before), otherwise str """ self.load_details(refresh=True) return InfoBlock("Compliance", "Status").title @property def compliant(self): """Check if the VM is compliant Returns: :py:class:`NoneType` if the VM was never verified, otherwise :py:class:`bool` """ text = self.get_detail(properties=("Compliance", "Status")).strip().lower() if text == "never verified": return None elif text.startswith("non-compliant"): return False elif text.startswith("compliant"): return True else: raise ValueError( "{} is not a known state for compliance".format(text)) @property def console_handle(self): ''' The basic algorithm for getting the consoles window handle is to get the appliances window handle and then iterate through the window_handles till we find one that is not the appliances window handle. Once we find this check that it has a canvas widget with a specific ID ''' browser = self.appliance.browser.widgetastic appliance_handle = browser.window_handle cur_handles = browser.selenium.window_handles logger.info("Current Window Handles: {}".format(cur_handles)) for handle in cur_handles: if handle != appliance_handle: # FIXME: Add code to verify the tab has the correct widget # for a console tab. return handle def delete(self, cancel=False, from_details=False): """Deletes the VM/Instance from the VMDB. Args: cancel: Whether to cancel the action in the alert. from_details: Whether to use the details view or list view. """ if from_details: self.load_details(refresh=True) cfg_btn(self.REMOVE_SINGLE, invokes_alert=True) else: self.find_quadicon().check() cfg_btn(self.REMOVE_SELECTED, invokes_alert=True) sel.handle_alert(cancel=cancel) @property def exists(self): """Checks presence of the quadicon in the CFME.""" try: self.find_quadicon() return True except VmOrInstanceNotFound: return False @property def ip_address(self): """Fetches IP Address of VM""" return self.provider.mgmt.get_ip_address(self.name) @property def is_retired(self): """"Check retirement status of vm""" self.summary.reload() if self.summary.lifecycle.retirement_date.text_value.lower( ) != 'never': try: return self.summary.lifecycle.retirement_state.text_value.lower( ) == 'retired' except AttributeError: return False else: return False def find_quadicon(self, from_any_provider=False, use_search=True): """Find and return a quadicon belonging to a specific vm Args: from_any_provider: Whether to look for it anywhere (root of the tree). Useful when looking up archived or orphaned VMs Returns: entity of appropriate type Raises: VmOrInstanceNotFound """ # todo :refactor this method replace it with vm methods like get_state if from_any_provider: view = navigate_to(self, 'All') else: view = navigate_to(self, 'AllForProvider', use_resetter=False) if 'Grid View' != view.toolbar.view_selector.selected: view.toolbar.view_selector.select('Grid View') if use_search: search.normal_search(self.name) try: return view.entities.get_entity(by_name=self.name, surf_pages=True) except ItemNotFound: raise VmOrInstanceNotFound("VM '{}' not found in UI!".format( self.name)) def get_detail(self, properties=None, icon_href=False): """Gets details from the details infoblock The function first ensures that we are on the detail page for the specific VM/Instance. Args: properties: An InfoBlock title, followed by the Key name, e.g. "Relationships", "Images" Returns: A string representing the contents of the InfoBlock's value. """ self.load_details(refresh=True) if icon_href: return InfoBlock.icon_href(*properties) else: return InfoBlock.text(*properties) def open_console(self, console='VM Console', invokes_alert=False, cancel=False): """ Initiates the opening of one of the console types supported by the Access button. Presently we only support VM Console, which is the HTML5 Console. In case of VMware provider it could be VMRC, VNC/HTML5, WebMKS, but we only support VNC/HTML5. Possible values for 'console' could be 'VM Console' and 'Web Console', but Web Console is not supported as well. Args: console: one of the supported console types given by the Access button. invokes_alert: If the particular console will invoke a CFME popup/alert setting this to true will handle this. cancel: Allows one to cancel the operation if the popup/alert occurs. """ # TODO: implement vmrc vm console if console not in ['VM Console']: raise NotImplementedError( 'Not supported console type: {}'.format(console)) view = navigate_to(self, 'Details') # Click console button given by type view.toolbar.access.item_select( console, handle_alert=None if invokes_alert is False else True) # Get the consoles window handle, and then create a VMConsole object, and store # the VMConsole object aside. console_handle = self.console_handle if console_handle is None: raise TypeError("Console handle should not be None") appliance_handle = self.appliance.browser.widgetastic.window_handle logger.info("Creating VMConsole:") logger.info(" appliance_handle: {}".format(appliance_handle)) logger.info(" console_handle: {}".format(console_handle)) logger.info(" name: {}".format(self.name)) self.vm_console = VMConsole(appliance_handle=appliance_handle, console_handle=console_handle, vm=self) def open_details(self, properties=None): """Clicks on details infoblock""" self.load_details(refresh=True) sel.click(InfoBlock(*properties)) @classmethod def get_first_vm(cls, provider): """Get first VM/Instance.""" # todo: move this to base provider ? view = navigate_to(cls, 'AllForProvider', provider=provider) return view.entities.get_first_entity() @property def last_analysed(self): """Returns the contents of the ``Last Analysed`` field in summary""" return self.get_detail(properties=('Lifecycle', 'Last Analyzed')).strip() def load_details(self, refresh=False): """Navigates to an VM's details page. Args: refresh: Refreshes the VM page if already there Raises: VmOrInstanceNotFound: When unable to find the VM passed """ navigate_to(self, 'Details', use_resetter=False) if refresh: toolbar.refresh() self.browser.plugin.ensure_page_safe() def open_edit(self): """Loads up the edit page of the object.""" self.load_details(refresh=True) cfg_btn(self.TO_OPEN_EDIT) def open_timelines(self): """Navigates to an VM's timeline page. Returns: :py:class:`TimelinesView` object """ return navigate_to(self, 'Timelines') def rediscover(self): """Deletes the VM from the provider and lets it discover again""" self.delete(from_details=True) self.wait_for_delete() self.provider.refresh_provider_relationships() self.wait_to_appear() def rediscover_if_analysis_data_present(self): """Rediscovers the object if it has some analysis data present. Returns: Boolean if the rediscovery happened. """ if self.last_analysed.lower() != 'never': self.rediscover() return True return False def refresh_relationships(self, from_details=False, cancel=False, from_any_provider=False): """Executes a refresh of relationships. Args: from_details: Whether or not to perform action from instance details page cancel: Whether or not to cancel the refresh relationships action """ if from_details: self.load_details() else: self.find_quadicon(from_any_provider=from_any_provider).check() cfg_btn('Refresh Relationships and Power States', invokes_alert=True) sel.handle_alert(cancel=cancel) @property def retirement_date(self): """Returns the retirement date of the selected machine, or 'Never' Returns: :py:class:`str` object """ return self.get_detail(properties=("Lifecycle", "Retirement Date")).strip() def smartstate_scan(self, cancel=False, from_details=False): """Initiates fleecing from the UI. Args: cancel: Whether or not to cancel the refresh relationships action from_details: Whether or not to perform action from instance details page """ if from_details: self.load_details(refresh=True) else: self.find_quadicon().check() cfg_btn('Perform SmartState Analysis', invokes_alert=True) sel.handle_alert(cancel=cancel) def wait_to_disappear(self, timeout=600, load_details=True): """Wait for a VM to disappear within CFME Args: timeout: time (in seconds) to wait for it to appear """ wait_for(lambda: self.exists, num_sec=timeout, delay=30, fail_func=sel.refresh, fail_condition=True, message="wait for vm to not exist") wait_for_delete = wait_to_disappear # An alias for more fitting verbosity def wait_to_appear(self, timeout=600, load_details=True): """Wait for a VM to appear within CFME Args: timeout: time (in seconds) to wait for it to appear load_details: when found, should it load the vm details """ def _refresh(): self.provider.refresh_provider_relationships() self.appliance.browser.widgetastic.browser.refresh( ) # strange because ViaUI wait_for(lambda: self.exists, num_sec=timeout, delay=5, fail_func=_refresh, message="wait for vm to appear") if load_details: self.load_details() def set_ownership(self, user=None, group=None, click_cancel=False, click_reset=False): """Set ownership of the VM/Instance or Template/Image""" self.find_quadicon(use_search=False).click() cfg_btn('Set Ownership') if click_reset: action = form_buttons.reset msg_assert = partial(flash.assert_message_match, 'All changes have been reset') elif click_cancel: action = form_buttons.cancel msg_assert = partial(flash.assert_success_message, 'Set Ownership was cancelled by the user') else: action = form_buttons.save msg_assert = partial( flash.assert_success_message, 'Ownership saved for selected {}'.format(self.VM_TYPE)) fill(set_ownership_form, { 'user_name': user, 'group_name': group }, action=action) msg_assert() def unset_ownership(self): """Unset ownership of the VM/Instance or Template/Image""" # choose the vm code comes here self.find_quadicon(use_search=False).click() cfg_btn('Set Ownership') fill(set_ownership_form, { 'user_name': '<No Owner>', 'group_name': 'EvmGroup-administrator' }, action=form_buttons.save) flash.assert_success_message('Ownership saved for selected {}'.format( self.VM_TYPE))
'save_button': form_buttons.save, }) snapshot_tree = Tree("//div[@id='snapshots_treebox']/ul") snapshot_form = Form( fields=[('name', Input('name')), ('descrition', Input('description')), ('snapshot_memory', Input('snap_memory')), ( 'create_button', create_button), ('cancel_button', form_buttons.cancel)]) retirement_date_form = Form( fields=[('retirement_date_text', Calendar("miq_date_1")), ('retirement_warning_select', Select("//select[@id='retirement_warn']"))]) retire_remove_button = "//span[@id='remove_button']/a/img" vm_templates_tree = partial(accordion.tree, "VMs & Templates") vms_tree = partial(accordion.tree, "VMs") templates_tree = partial(accordion.tree, "Templates") drift_table = CheckboxTable({ version.LOWEST: "//table[@class='style3']", "5.4": "//th[normalize-space(.)='Timestamp']/ancestor::table[1]" })
from utils import version, deferred_verpick from utils.pretty import Pretty from widgetastic_manageiq import TimelinesView # Forms discover_form = Form( fields=[('discover_select', AngularSelect("discover_type_selected"), { "appeared_in": "5.5" }), ('username', "#userid"), ('password', "#password"), ('password_verify', "#verify"), ('start_button', form_buttons.FormButton("Start the Host Discovery"))]) properties_form_55 = Form(fields=[ ('type_select', { version.LOWEST: Select('select#server_emstype'), '5.5': AngularSelect("emstype") }), ('azure_tenant_id', Input("azure_tenant_id")), ('name_text', Input("name")), ('hostname_text', Input("hostname")), ('ipaddress_text', Input("ipaddress"), { "removed_since": "5.4.0.0.15" }), ('region_select', { version.LOWEST: Select("select#provider_region"), "5.5": AngularSelect("provider_region") }), ('api_port', Input({ version.LOWEST: "port", "5.5": "api_port",
details_page = Region(infoblock_type='detail') # Forms discover_form = Form( fields=[('rhevm_chk', Input("discover_type_rhevm") ), ('vmware_chk', Input("discover_type_virtualcenter")), ('scvmm_chk', Input("discover_type_scvmm")), ('from_0', Input("from_first")), ('from_1', Input("from_second")), ('from_2', Input("from_third")), ('from_3', Input("from_fourth")), ('to_3', Input("to_fourth")), ('start_button', FormButton("Start the Host Discovery"))]) properties_form = Form( fields=[('type_select', { version.LOWEST: Select('select#server_emstype'), '5.5': AngularSelect("server_emstype") }), ( 'name_text', Input("name")), ('hostname_text', { version.LOWEST: Input("hostname"), }), ('ipaddress_text', Input("ipaddress"), { "removed_since": "5.4.0.0.15" }), ('api_port', Input("port")), ('sec_protocol', { version.LOWEST: Select("select#security_protocol"), '5.5': AngularSelect("security_protocol") }), ('sec_realm', Input("realm"))]) properties_form_56 = TabStripForm(
# Forms discover_form = Form(fields=[ ('rhevm_chk', "//input[@id='discover_type_rhevm']"), ('vmware_chk', "//input[@id='discover_type_virtualcenter']"), ('from_0', "//*[@id='from_first']"), ('from_1', "//*[@id='from_second']"), ('from_2', "//*[@id='from_third']"), ('from_3', "//*[@id='from_fourth']"), ('to_3', "//*[@id='to_fourth']"), ('start_button', "//input[@name='start']"), ('cancel_button', "//input[@name='cancel']"), ]) properties_form = Form(fields=[ ('type_select', Select("//*[@id='server_emstype']")), ('name_text', "//*[@id='name']"), ('hostname_text', "//*[@id='hostname']"), ('ipaddress_text', "//*[@id='ipaddress']"), ('api_port', "//*[@id='port']"), ]) credential_form = Form( fields=[('default_button', "//div[@id='auth_tabs']/ul/li/a[@href='#default']" ), ('default_principal', "//*[@id='default_userid']" ), ('default_secret', "//*[@id='default_password']" ), ('default_verify_secret', "//*[@id='default_verify']"), ('candu_button', "//div[@id='auth_tabs']/ul/li/a[@href='#metrics']" ), ('candu_principal', "//*[@id='metrics_userid']" ), ('candu_secret', "//*[@id='metrics_password']"
def select_from_row(self, row): return Select(sel.element("./td/select", root=row))
def _mkitem(index): return RateFormItem( (By.CSS_SELECTOR, "input#rate_" + str(index)), Select((By.CSS_SELECTOR, "select#per_time_" + str(index))))
class Visual(Updateable): pretty_attrs = ['name'] item_form = Form(fields=[ ('grid_view', { version.LOWEST: Select('//select[@id="perpage_grid"]'), "5.5": AngularSelect('perpage_grid') }), ('tile_view', { version.LOWEST: Select('//select[@id="perpage_tile"]'), "5.5": AngularSelect("perpage_tile") }), ('list_view', { version.LOWEST: Select('//select[@id="perpage_list"]'), "5.5": AngularSelect("perpage_list") }), ('reports', { version.LOWEST: Select('//select[@id="perpage_reports"]'), "5.5": AngularSelect("perpage_reports") }), ]) startpage_form = Form( fields=[('login_page', { version.LOWEST: Select('//select[@id="start_page"]'), "5.5": AngularSelect("start_page") })]) quadicons_form = Form(fields=[ ('infra_provider_quad', CFMECheckbox("quadicons_ems")), ('cloud_provider_quad', CFMECheckbox("quadicons_ems_cloud")), ('host_quad', CFMECheckbox("quadicons_host")), ('datastore_quad', CFMECheckbox("quadicons_storage")), ('datastoreitem_quad', Input("quadicons_storageitem")), ('vm_quad', CFMECheckbox("quadicons_vm")), ('vmitem_quad', Input("quadicons_vmitem")), ('template_quad', CFMECheckbox("quadicons_miq_template")), ]) display_form = Form(fields=[ ('chart_theme', { version.LOWEST: Select('//select[@id="display_reporttheme"]'), "5.5": AngularSelect("display_reporttheme") }), ('time_zone', { version.LOWEST: Select('//select[@id="display_timezone"]'), "5.5": AngularSelect("display_timezone") }), ]) save_button = form_buttons.FormButton("Add this Time Profile") @property def grid_view_limit(self): sel.force_navigate("my_settings_visual") return int(self.item_form.grid_view.first_selected_option_text) @grid_view_limit.setter def grid_view_limit(self, value): sel.force_navigate("my_settings_visual") fill(self.item_form.grid_view, str(value)) sel.click(form_buttons.save) @property def tile_view_limit(self): sel.force_navigate("my_settings_visual") return int(self.item_form.tile_view.first_selected_option_text) @tile_view_limit.setter def tile_view_limit(self, value): sel.force_navigate("my_settings_visual") fill(self.item_form.tile_view, str(value)) sel.click(form_buttons.save) @property def list_view_limit(self): sel.force_navigate("my_settings_visual") return int(self.item_form.list_view.first_selected_option_text) @list_view_limit.setter def list_view_limit(self, value): sel.force_navigate("my_settings_visual") fill(self.item_form.list_view, str(value)) sel.click(form_buttons.save) @property def report_view_limit(self): sel.force_navigate("my_settings_visual") return int(self.item_form.reports.first_selected_option_text) @report_view_limit.setter def report_view_limit(self, value): sel.force_navigate("my_settings_visual") fill(self.item_form.reports, str(value)) sel.click(form_buttons.save) @property def login_page(self): sel.force_navigate("my_settings_visual") return int(self.startpage_form.login_page.first_selected_option_text) @login_page.setter def login_page(self, value): sel.force_navigate("my_settings_visual") fill(self.startpage_form.login_page, str(value)) sel.click(form_buttons.save) @property def infra_provider_quad(self): sel.force_navigate("my_settings_visual") return self.infra_provider_quad @infra_provider_quad.setter def infra_provider_quad(self, value): sel.force_navigate("my_settings_visual") fill(self.quadicons_form.infra_provider_quad, value) sel.click(form_buttons.save) @property def host_quad(self): sel.force_navigate("my_settings_visual") return self.host_quad @host_quad.setter def host_quad(self, value): sel.force_navigate("my_settings_visual") fill(self.quadicons_form.host_quad, value) sel.click(form_buttons.save) @property def datastore_quad(self): sel.force_navigate("my_settings_visual") return self.datastore_quad @datastore_quad.setter def datastore_quad(self, value): sel.force_navigate("my_settings_visual") fill(self.quadicons_form.datastore_quad, value) sel.click(form_buttons.save) @property def vm_quad(self): sel.force_navigate("my_settings_visual") return self.vm_quad @vm_quad.setter def vm_quad(self, value): sel.force_navigate("my_settings_visual") fill(self.quadicons_form.vm_quad, value) sel.click(form_buttons.save) @property def template_quad(self): sel.force_navigate("my_settings_visual") return self.template_quad @template_quad.setter def template_quad(self, value): sel.force_navigate("my_settings_visual") fill(self.quadicons_form.template_quad, value) sel.click(form_buttons.save) def check_image_exists(self): name = Quadicon.get_first_quad_title() quad = Quadicon(name, None) return quad.check_for_single_quadrant_icon @property def cloud_provider_quad(self): sel.force_navigate("my_settings_visual") return self.cloud_provider_quad @cloud_provider_quad.setter def cloud_provider_quad(self, value): sel.force_navigate("my_settings_visual") fill(self.quadicons_form.cloud_provider_quad, value) sel.click(form_buttons.save) @property def timezone(self): sel.force_navigate("my_settings_visual") return self.display_form.time_zone.first_selected_option_text @timezone.setter def timezone(self, value): sel.force_navigate("my_settings_visual") fill(self.display_form.time_zone, str(value)) sel.click(form_buttons.save)
from utils.update import Updateable from utils.wait import wait_for from utils import version from utils.pretty import Pretty # Page specific locators details_page = Region(infoblock_type='detail') properties_form = Form(fields=[ ('name_text', Input("name")), ('hostname_text', Input("hostname")), ('ipaddress_text', Input("ipaddress"), { "removed_since": "5.4.0.0.15" }), ('custom_ident_text', Input("custom")), ('host_platform', Select('//select[@id="user_assigned_os"]')), ('ipmi_address_text', Input("ipmi_address")), ('mac_address_text', Input("mac_address")), ]) credential_form = Form(fields=[ ('default_button', "//div[@id='auth_tabs']/ul/li/a[@href='#default']"), ('default_principal', Input("default_userid")), ('default_secret', Input("default_password")), ('default_verify_secret', Input("default_verify")), ('ipmi_button', "//div[@id='auth_tabs']/ul/li/a[@href='#ipmi']"), ('ipmi_principal', Input("ipmi_userid")), ('ipmi_secret', Input("ipmi_password")), ('ipmi_verify_secret', Input("ipmi_verify")), ('validate_btn', form_buttons.validate), ('validate_multi_host', form_buttons.validate_multi_host),
class MultiBoxSelect(object): def __init__(self, unselected, selected, to_unselected, to_selected, remove_all=None): self._unselected = Select(unselected, multi=True) self._selected = Select(selected, multi=True) self._to_unselected = to_unselected self._to_selected = to_selected self._remove_all = remove_all def _move_to_unselected(self): sel.click(sel.element(self._to_unselected)) return not any(map(flash.is_error, flash.get_all_messages())) def _move_to_selected(self): sel.click(sel.element(self._to_selected)) return not any(map(flash.is_error, flash.get_all_messages())) def _select_unselected(self, *items): for item in items: sel.select(self._unselected, item) def _select_selected(self, *items): for item in items: sel.select(self._selected, item) def _clear_selection(self): self._unselected.deselect_all() self._selected.deselect_all() def remove_all(self): """ Flush the list of selected items. Returns: :py:class:`bool` with success. """ if self._remove_all is None: raise NotImplementedError("'Remove all' button was not specified!") sel.click(sel.element(self._remove_all)) return not any(map(flash.is_error, flash.get_all_messages())) def add(self, *values, **kwargs): """ Mark items for selection and then clicks the button to select them. Args: *values: Values to select Keywords: flush: By using `flush` keyword, the selected items list is flushed prior to selecting new ones Retuns: :py:class:`bool` with success. """ if kwargs.get("flush", False): self.remove_all() self._clear_selection() self._select_unselected(*values) return self._move_to_selected() def remove(self, *values): """ Mark items for deselection and then clicks the button to deselect them. Args: *values: Values to deselect Returns: :py:class:`bool` with success. """ self._clear_selection() self._select_selected(*values) return self._move_to_unselected()
tab_form = Form( fields=[('tab_label', Input("tab_label")), ('tab_desc', Input("tab_description"))]) box_form = Form( fields=[('box_label', Input("group_label")), ('box_desc', Input("group_description"))]) element_form = Form( fields=[('ele_label', Input("field_label")), ( 'ele_name', Input("field_name")), ('ele_desc', Input("field_description")), ('choose_type', Select("//select[@id='field_typ']") ), ('default_text_box', Input("field_default_value") ), ('field_required', Input("field_required") ), ('field_past_dates', Input("field_past_dates") ), ('field_entry_point', Input("field_entry_point")), ('field_show_refresh_button', Input("field_show_refresh_button") ), ('entry_value', Input("entry[value]")), ('entry_description', Input("entry[description]")), ('add_entry_button', Input("accept")), ('field_category', Select("//select[@id='field_category']") ), ('text_area', Input("field_default_value") ), ('dynamic_chkbox', Input("field_dynamic") ), ('apply_btn', '//a[@title="Apply"]')]) dialogs_table = SplitTable(header_data=('//div[@class="xhdr"]/table/tbody', 1),
class MultiBoxSelect(object): """ Common UI element for selecting multiple items. Presence in eg. Control/Explorer/New Policy Profile (for selecting policies) Args: unselected: Locator for the left (unselected) list of items. selected: Locator for the right (selected) list of items. to_unselected: Locator for a button which moves items from right to left (unselecting) to_selected: Locator for a button which moves items from left to right (selecting) remove_all: If present, locator for a button which unselects all items (Default None) """ def __init__(self, unselected, selected, to_unselected, to_selected, remove_all=None): self._unselected = Select(unselected, multi=True) self._selected = Select(selected, multi=True) self._to_unselected = to_unselected self._to_selected = to_selected self._remove_all = remove_all def _move_to_unselected(self): """ Clicks the button for moving items from selected to unselected. Returns: :py:class:`bool` with success. """ sel.click(sel.element(self._to_unselected)) return not any(map(flash.is_error, flash.get_all_messages())) def _move_to_selected(self): """ Clicks the button for moving items from unselected to selected. Returns: :py:class:`bool` with success. """ sel.click(sel.element(self._to_selected)) return not any(map(flash.is_error, flash.get_all_messages())) def _select_unselected(self, *items): """ Selects items in 'Unselected items' list Args: *items: Items to select """ for item in items: sel.select(self._unselected, item) def _select_selected(self, *items): """ Selects items in 'Selected items' list Args: *items: Items to select """ for item in items: sel.select(self._selected, item) def _clear_selection(self): """ Unselects all items in both lists to ensure unwanted items don't travel in between. """ self._unselected.deselect_all() self._selected.deselect_all() def remove_all(self): """ Flush the list of selected items. Returns: :py:class:`bool` with success. """ if self._remove_all is None: raise NotImplementedError("'Remove all' button was not specified!") if len(self._selected.options) == 0: return # No need to flush sel.click(sel.element(self._remove_all)) return not any(map(flash.is_error, flash.get_all_messages())) def add(self, *values, **kwargs): """ Mark items for selection and then clicks the button to select them. Args: *values: Values to select Keywords: flush: By using `flush` keyword, the selected items list is flushed prior to selecting new ones Returns: :py:class:`bool` with success. """ if kwargs.get("flush", False): self.remove_all() self._clear_selection() self._select_unselected(*values) if len(self._unselected.all_selected_options) > 0: return self._move_to_selected() else: return True def remove(self, *values): """ Mark items for deselection and then clicks the button to deselect them. Args: *values: Values to deselect Returns: :py:class:`bool` with success. """ self._clear_selection() self._select_selected(*values) if len(self._selected.all_selected_options) > 0: return self._move_to_unselected() else: return True @classmethod def default(cls): """ The most common type of the MultiBoxSelect Returns: :py:class:`MultiBoxSelect` instance """ return cls( "//select[@id='choices_chosen']", "//select[@id='members_chosen']", "//a/img[contains(@alt, 'Remove selected')]", "//a/img[contains(@alt, 'Move selected')]", "//a/img[contains(@alt, 'Remove all')]", )
from . import Report from cfme.fixtures import pytest_selenium as sel from cfme.intelligence.reports.ui_elements import ExternalRSSFeed, MenuShortcuts, Timer from cfme.web_ui import (CheckboxSelect, Form, InfoBlock, Select, ShowingInputs, accordion, fill, toolbar, Input) from navmazing import NavigateToObject, NavigateToSibling from cfme.web_ui import flash, form_buttons, summary_title from utils import version from utils.update import Updateable from utils.pretty import Pretty from utils.wait import wait_for from utils.appliance import Navigatable from utils.appliance.implementations.ui import navigator, CFMENavigateStep, navigate_to visibility_obj = ShowingInputs( Select("//select[@id='visibility_typ']"), CheckboxSelect({ version.LOWEST: "//td[normalize-space(.)='User Roles']/../td/table", "5.5": "//label[normalize-space(.)='User Roles']/../div/table" }), min_values=1) class Widget(Updateable, Pretty, Navigatable): TITLE = None DETAIL_PAGE = None WAIT_STATES = {"Queued", "Running"} status_info = InfoBlock("Status")