def test_sdn_crud(provider, appliance): """ Test for functional addition of network manager with cloud provider and functional references to components on detail page Prerequisites: Cloud provider in cfme """ view = navigate_to(provider, 'Details') net_prov_name = view.entities.summary("Relationships").get_text_of("Network Manager") collection = appliance.collections.network_providers network_provider = collection.instantiate(prov_class=NetworkProvider, name=net_prov_name) view = navigate_to(network_provider, 'Details') parent_name = view.entities.relationships.get_text_of("Parent Cloud Provider") assert parent_name == provider.name testing_list = ["Cloud Networks", "Cloud Subnets", "Network Routers", "Security Groups", "Floating IPs", "Network Ports", "Load Balancers"] for testing_name in testing_list: view = navigate_to(network_provider, 'Details') view.entities.relationships.click_at(testing_name) provider.delete_if_exists(cancel=False) provider.wait_for_delete() assert not network_provider.exists
def test_distributed_vm_power_control(request, test_vm, virtualcenter_provider, verify_vm_running, register_event, soft_assert): """Tests that a replication parent appliance can control the power state of a VM being managed by a replication child appliance. Metadata: test_flag: replication """ appl1, appl2 = get_replication_appliances() def finalize(): appl1.destroy() appl2.destroy() request.addfinalizer(finalize) appl1.ipapp.browser_steal = True with appl1.ipapp: configure_db_replication(appl2.hostname) virtualcenter_provider.create() wait_for_a_provider() appl2.ipapp.browser_steal = True with appl2.ipapp: register_event(target_type='VmOrTemplate', target_name=test_vm.name, event_type='request_vm_poweroff') register_event(target_type='VmOrTemplate', target_name=test_vm.name, event_type='vm_poweroff') test_vm.power_control_from_cfme(option=test_vm.POWER_OFF, cancel=False) navigate_to(test_vm.provider, 'Details') test_vm.wait_for_vm_state_change(desired_state=test_vm.STATE_OFF, timeout=900) soft_assert(test_vm.find_quadicon().data['state'] == 'currentstate-off') soft_assert( not test_vm.provider.mgmt.is_vm_running(test_vm.name), "vm running")
def all(self): if self.filters.get('parent'): view = navigate_to(self.filters.get('parent'), 'NetworkRouters') else: view = navigate_to(self, 'All') list_networks_obj = view.entities.get_all(surf_pages=True) return [self.instantiate(name=r.name) for r in list_networks_obj]
def test_automate_method_inputs_crud(klass): """ Polarion: assignee: dmisharo casecomponent: Automate initialEstimate: 1/8h """ method = klass.methods.create( name=fauxfactory.gen_alphanumeric(), display_name=fauxfactory.gen_alphanumeric(), location='inline', script='blah', inputs={ 'foo': {'data_type': 'string'}, 'bar': {'data_type': 'integer', 'default_value': '42'}} ) assert method.exists view = navigate_to(method, 'Details') assert view.inputs.is_displayed assert view.inputs.read() == { 'foo': {'Data Type': 'string', 'Default Value': ''}, 'bar': {'Data Type': 'integer', 'Default Value': '42'}, } with update(method): method.inputs = {'different': {'default_value': 'value'}} view = navigate_to(method, 'Details') assert view.inputs.is_displayed assert view.inputs.read() == { 'different': {'Data Type': 'string', 'Default Value': 'value'}, } with update(method): method.inputs = {} view = navigate_to(method, 'Details') assert not view.inputs.is_displayed method.delete()
def exists(self): try: navigate_to(self, 'Details') except (NavigationDestinationNotFound, CandidateNotFound): return False else: return True
def exists(self): try: navigate_to(self, 'Details') except ItemNotFound: return False else: return True
def test_no_template_power_control(provider, soft_assert): """ Ensures that no power button is displayed for templates. Prerequisities: * An infra provider that has some templates. Steps: * Open the view of all templates of the provider * Verify the Power toolbar button is not visible * Select some template using the checkbox * Verify the Power toolbar button is not visible * Click on some template to get into the details page * Verify the Power toolbar button is not visible """ view = navigate_to(provider, 'ProviderTemplates') view.toolbar.view_selector.select('Grid View') soft_assert(not view.toolbar.power.is_enabled, "Power displayed in template grid view!") # Ensure selecting a template doesn't cause power menu to appear templates = list(get_all_vms(True)) template_name = random.choice(templates) selected_template = VM.factory(template_name, provider, template=True) # Check the power button with checking the quadicon view = navigate_to(selected_template, 'AllForProvider', use_resetter=False) entity = view.entities.get_entity(name=selected_template.name, surf_pages=True) entity.check() soft_assert(not view.toolbar.power.is_enabled, "Power displayed when template quadicon checked!") # Ensure there isn't a power button on the details page entity.click() soft_assert(not view.toolbar.power.is_enabled, "Power displayed in template details!")
def test_control_identical_descriptions(request, create_function, collections, appliance): """CFME should not allow to create policy, alerts, profiles, actions and others to be created if the item with the same description already exists. Steps: * Create an item * Create the same item again Result: The item shouldn't be created. Polarion: assignee: jdupuy casecomponent: Control caseimportance: low initialEstimate: 1/12h """ args, kwargs = create_function.fn(request, collections[create_function.name]) flash = appliance.browser.create_view(ControlExplorerView).flash try: collections[create_function.name].create(*args, **kwargs) except (TimedOutError, AssertionError): flash.assert_message("Description has already been taken") # force navigation away from the page so the browser is not stuck on the edit page navigate_to(appliance.server, 'ControlExplorer', force=True)
def power_control_from_cfme(self, *args, **kwargs): """Power controls a VM from within CFME using details or collection Raises: InstanceNotFound: the instance wasn't found when navigating OptionNotAvailable: option param is not visible or enabled """ # TODO push this to common.vm when infra vm classes have widgets if not kwargs.get('option'): raise ValueError('Need to provide option for power_control_from_cfme, no default.') if kwargs.get('from_details', True): view = navigate_to(self, 'Details') else: view = navigate_to(self, 'AllForProvider') view.toolbar.view_selector.select('List View') try: row = view.entities.get_entity(name=self.name) except ItemNotFound: raise InstanceNotFound('Failed to find instance in table: {}'.format(self.name)) row.check() # cancel is the kwarg, when true we want item_select to dismiss the alert, flip the bool view.toolbar.power.item_select(kwargs.get('option'), handle_alert=not kwargs.get('cancel', False))
def exists(self): """ Returns True if dialog exists""" try: navigate_to(self, 'Details') return True except (CandidateNotFound, ItemNotFound): return False
def test_scope_windows_registry_stuck(request, appliance, infra_provider): """If you provide Scope checking windows registry, it messes CFME up. Recoverable. Polarion: assignee: jdupuy casecomponent: Control caseimportance: low initialEstimate: 1/6h """ policy = appliance.collections.policies.create( VMCompliancePolicy, "Windows registry scope glitch testing Compliance Policy", active=True, scope=r"fill_registry(HKLM\SOFTWARE\Microsoft\CurrentVersion\Uninstall\test, " r"some value, INCLUDES, some content)" ) request.addfinalizer(lambda: policy.delete() if policy.exists else None) profile = appliance.collections.policy_profiles.create( "Windows registry scope glitch testing Compliance Policy", policies=[policy] ) request.addfinalizer(lambda: profile.delete() if profile.exists else None) # Now assign this malformed profile to a VM # not assuming tht infra_provider is actually an InfraProvider type vm = infra_provider.appliance.collections.infra_vms.all()[0] vm.assign_policy_profiles(profile.description) # It should be screwed here, but do additional check navigate_to(appliance.server, 'Dashboard') view = navigate_to(appliance.collections.infra_vms, 'All') assert "except" not in view.entities.title.text.lower() vm.unassign_policy_profiles(profile.description)
def test_scale_provider_down(provider, host, has_mistral_service): """Scale down Openstack Infrastructure provider Metadata: test_flag: openstack_scale""" host.toggle_maintenance_mode() host_uuid = host.name.split()[0] # cut off deployment role part from host's name wait_for(lambda: provider.mgmt.iapi.node.get(host_uuid).maintenance, timeout=600, delay=5) wait_for(provider.is_refreshed, func_kwargs=dict(refresh_delta=10), timeout=600) host.browser.refresh() view = navigate_to(host, 'Details') wait_for( lambda: view.entities.summary('Properties').get_text_of('Maintenance Mode') == 'Enabled', delay=15, timeout=300, message="Maintenance Mode of host {} becomes Enabled".format(host.name), fail_func=host.browser.refresh) assert view.entities.summary('Properties').get_text_of('Maintenance Mode') == 'Enabled' provider.scale_down() wait_for(lambda: provider.mgmt.iapi.node.get(host_uuid).provision_state == 'available', delay=5, timeout=1200) host.name = host_uuid # host's name is changed after scale down host.browser.refresh() wait_for(lambda: host.exists, delay=15, timeout=600, message="Hostname changed to {} after scale down".format(host.name), fail_func=provider.browser.refresh) view = navigate_to(host, 'Details') wait_for( lambda: view.entities.summary('Openstack Hardware').get_text_of('Provisioning State') == 'available', delay=15, timeout=600, message="Provisioning State of host {} is available".format(host.name), fail_func=host.browser.refresh) prov_state = view.entities.summary('Openstack Hardware').get_text_of('Provisioning State') assert prov_state == 'available'
def test_sdn_crud(provider, appliance): """ Test for functional addition of network manager with cloud provider and functional references to components on detail page Prerequisites: Cloud provider in cfme Metadata: test_flag: sdn """ collection = appliance.collections.network_providers.filter({'provider': provider}) network_provider = collection.all()[0] view = navigate_to(network_provider, 'Details') parent_name = view.entities.relationships.get_text_of("Parent Cloud Provider") assert parent_name == provider.name testing_list = ["Cloud Networks", "Cloud Subnets", "Network Routers", "Security Groups", "Floating IPs", "Network Ports", "Load Balancers"] for testing_name in testing_list: view = navigate_to(network_provider, 'Details') view.entities.relationships.click_at(testing_name) provider.delete_if_exists(cancel=False) provider.wait_for_delete() assert not network_provider.exists
def test_paginator_details_page(appliance, place_info, schedule): """ Check paginator is visible for access control pages + schedules. If paginator is present, check that all options are present in items per page. Polarion: assignee: anikifor casecomponent: WebUI caseimportance: medium initialEstimate: 1/10h Bugzilla: 1515952 """ place_name, place_class, place_navigation, paginator_expected_result = place_info if place_name == 'tag': category = appliance.collections.categories.instantiate( name='department', display_name='Department') test_class = category.collections.tags view = navigate_to(test_class, place_navigation) else: test_class = place_class if place_class else getattr(appliance.collections, place_name) view = navigate_to(test_class, 'All') table = view.table if hasattr(view, 'table') else view.entities.table if place_navigation == 'Details': table[0].click() assert check_paginator_for_page(view) == paginator_expected_result if check_paginator_for_page(view): paginator = view.paginator items_selector = Dropdown(view, '{} Items'.format(paginator.items_per_page)) msg = 'Not all options are present in items per page' if view.extra.appliance.version < '5.11': assert set(items_selection_5_10) == set(items_selector.items), msg else: assert set(items_selection) == set(items_selector.items), msg
def test_containers_summary_objects(provider, soft_assert): """ Containers overview page > Widgets > Widgets summary This test checks that the amount of a selected object in the system is shown correctly in the widgets in the Overview menu Steps: * Goes to Compute --> Containers --> Overview * Checks how many objects are shown in the selected widget * Goes to Containers summary page and checks how many objects are shown there. * Checks the amount is equal Polarion: assignee: juwatts caseimportance: medium casecomponent: Containers initialEstimate: 1/6h """ view = navigate_to(ContainersOverview, 'All') # Collecting status boxes values from overview page cards status_box_values = {obj: view.status_cards(obj.PLURAL.split(' ')[-1]).value for obj in tested_objects} # Comparing to the values in the relationships tables: view = navigate_to(provider, 'Details') ui_val_fields = view.entities.summary('Relationships').fields for obj in tested_objects: sb_val = status_box_values[obj] for ui_val_field in ui_val_fields: if obj.PLURAL in ui_val_field: ui_val = int(view.entities.summary('Relationships').get_text_of(ui_val_field)) soft_assert(sb_val == ui_val, '{}: Mismatch between status box ({}) value in Containers overview' 'and provider\'s relationships table ({}):' .format(obj.PLURAL, sb_val, ui_val)) else: continue
def _get_deployments_page(provider, server): if server: # if server instance is provided navigate through server page return navigate_to(server, 'ServerDeployments') elif provider: # if provider instance is provided navigate through provider page return navigate_to(provider, 'ProviderDeployments') else: # if None(provider and server) given navigate through all middleware deployments page return navigate_to(MiddlewareDeployment, 'All')
def _get_datasources_page(provider=None, server=None): if server: # if server instance is provided navigate through server page return navigate_to(server, 'ServerDatasources') elif provider: # if provider instance is provided navigate through provider page return navigate_to(provider, 'ProviderDatasources') else: # if None(provider and server) given navigate through all middleware datasources page return navigate_to(MiddlewareDatasource, 'All')
def exists(self): try: navigate_to(self, 'Details') except (ItemNotFound, NoSuchElementException): return False else: return True
def test_v2v_rbac(appliance, new_credential): """ Test migration with role-based access control Polarion: assignee: ytale initialEstimate: 1/2h caseimportance: high caseposneg: positive testtype: functional startsin: 5.10 casecomponent: V2V """ role = new_role(appliance=appliance, product_features=[(['Everything'], True)]) group = new_group(appliance=appliance, role=role.name) user = new_user(appliance=appliance, group=group, credential=new_credential) product_features = [(['Everything', 'Compute', 'Migration'], False)] role.update({'product_features': product_features}) with user: view = navigate_to(appliance.server, 'Dashboard') nav_tree = view.navigation.nav_item_tree() # Checks migration option is disabled in navigation assert 'Migration' not in nav_tree['Compute'], ('Migration found in nav tree, ' 'rbac should not allow this') product_features = [(['Everything'], True)] role.update({'product_features': product_features}) with user: view = navigate_to(appliance.server, 'Dashboard', wait_for_view=15) nav_tree = view.navigation.nav_item_tree() # Checks migration option is enabled in navigation assert 'Migration' in nav_tree['Compute'], ('Migration not found in nav tree, ' 'rbac should allow this')
def test_drift_analysis(request, ssa_vm, soft_assert, appliance, ssa_profile): """ Tests drift analysis is correct Metadata: test_flag: vm_analysis """ ssa_vm.load_details() drift_num_orig = 0 view = navigate_to(ssa_vm, "Details") drift_orig = view.entities.summary("Relationships").get_text_of("Drift History") if drift_orig != 'None': drift_num_orig = int(drift_orig) ssa_vm.smartstate_scan(wait_for_task_result=True) view = navigate_to(ssa_vm, "Details") wait_for( lambda: view.entities.summary("Relationships").get_text_of( "Drift History") == str(drift_num_orig + 1), delay=20, num_sec=360, message="Waiting for Drift History count to increase", fail_func=view.toolbar.reload.click ) drift_new = int(view.entities.summary("Relationships").get_text_of("Drift History")) # add a tag and a finalizer to remove it added_tag = Tag(display_name='Accounting', category=Category(display_name='Department')) ssa_vm.add_tag(added_tag) request.addfinalizer(lambda: ssa_vm.remove_tag(added_tag)) ssa_vm.smartstate_scan(wait_for_task_result=True) view = navigate_to(ssa_vm, "Details") wait_for( lambda: view.entities.summary("Relationships").get_text_of( "Drift History") == str(drift_new + 1), delay=20, num_sec=360, message="Waiting for Drift History count to increase", fail_func=view.toolbar.reload.click ) # check drift difference soft_assert(ssa_vm.equal_drift_results( '{} (1)'.format(added_tag.category.display_name), 'My Company Tags', 0, 1), "Drift analysis results are equal when they shouldn't be") # Test UI features that modify the drift grid drift_analysis_view = appliance.browser.create_view(DriftAnalysis) # Accounting tag should not be displayed, because it was changed to True drift_analysis_view.toolbar.same_values_attributes.click() soft_assert( not drift_analysis_view.drift_analysis.check_section_attribute_availability( '{}'.format(added_tag.category.display_name)), "{} row should be hidden, but not".format(added_tag.display_name)) # Accounting tag should be displayed now drift_analysis_view.toolbar.different_values_attributes.click() soft_assert( drift_analysis_view.drift_analysis.check_section_attribute_availability( '{} (1)'.format(added_tag.category.display_name)), "{} row should be visible, but not".format(added_tag.display_name))
def test_shuffle_first_level(appliance, group, report_menus): """ Polarion: assignee: pvala casecomponent: Reporting caseimportance: medium initialEstimate: 1/3h """ # Find a folder view = navigate_to(appliance.collections.reports, "All") tree = view.reports.tree.read_contents()[1] # Select some folder that has at least 3 children folders = map(lambda item: item[0], filter(lambda item: isinstance(item[1], list) and len(item[1]) >= 3, tree)) selected_folder = random.choice(folders) # Shuffle the order with report_menus.manage_folder(group, selected_folder) as folder: order = shuffle(folder.fields) for item in reversed(order): folder.move_first(item) # Now go and read the tree view = navigate_to(appliance.collections.reports, "All") view.reports.tree.click_path("All Reports", selected_folder) table = [row["Name"].text for row in view.reports_table] assert table == order, "The order differs!"
def test_domain_crud(request, enabled, appliance): """ Polarion: assignee: ghubale casecomponent: Automate caseimportance: critical initialEstimate: 1/30h tags: automate """ domain = appliance.collections.domains.create( name=fauxfactory.gen_alpha(), description=fauxfactory.gen_alpha(), enabled=enabled) request.addfinalizer(domain.delete_if_exists) assert domain.exists view = navigate_to(domain, 'Details') if enabled: assert 'Disabled' not in view.title.text else: assert 'Disabled' in view.title.text updated_description = "editdescription{}".format(fauxfactory.gen_alpha()) with update(domain): domain.description = updated_description view = navigate_to(domain, 'Edit') assert view.description.value == updated_description assert domain.exists domain.delete(cancel=True) assert domain.exists domain.delete() assert not domain.exists
def delete(self, cancel=False, wait=False): view = navigate_to(self, 'Details') view.toolbar.configuration.item_select('Remove this Key Pair', handle_alert=(not cancel)) # cancel doesn't redirect, confirmation does view.flush_widget_cache() if cancel: view = self.create_view(KeyPairDetailsView) else: view = self.create_view(KeyPairAllView) wait_for(lambda: view.is_displayed, fail_condition=False, num_sec=10, delay=1) # flash message only displayed if it was deleted if not cancel: view.entities.flash.assert_no_error() view.entities.flash.assert_success_message('Delete initiated for 1 Key Pair') if wait: def refresh(): self.provider.refresh_provider_relationships() view.browser.refresh() view.flush_widget_cache() view = navigate_to(self.parent, 'All') wait_for( lambda: self.name in view.entities.all_entity_names, message="Wait keypairs to disappear", fail_condition=True, num_sec=300, delay=5, fail_func=refresh )
def test_sdn_nsg_firewall_rules(provider, appliance, secgroup_with_rule): """ Pulls the list of firewall ports from Provider API and from appliance. Compare the 2 results. If same, then test is successful. Metadata: test_flag: sdn, inventory Polarion: assignee: mmojzis initialEstimate: 1/4h """ # Navigate to network provider. prov_collection = appliance.collections.network_providers.filter({'provider': provider}) network_provider = prov_collection.all()[0] network_provider.refresh_provider_relationships() wait_for(network_provider.is_refreshed, func_kwargs=dict(refresh_delta=10), timeout=600) view = navigate_to(network_provider, 'Details') parent_name = view.entities.relationships.get_text_of("Parent Cloud Provider") assert parent_name == provider.name secgrp_collection = appliance.collections.network_security_groups secgroup = [i for i in secgrp_collection.all() if i.name == secgroup_with_rule][0] view = navigate_to(secgroup, 'Details') if appliance.version < '5.10': # The table has one header row. The first non-header row has column # names. assert 'Port' == view.entities.firewall_rules[1][3].text assert '22' == view.entities.firewall_rules[2][3].text else: # The table has two header rows. We cannot access the second one with # widgetastic. So let's hope the column of index 3 is the Port Range # column. assert '22' == view.entities.firewall_rules[1][3].text
def add_tag(self, tag=None, cancel=False, reset=False, details=True): """ Add tag to tested item Args: tag: Tag object cancel: set True to cancel tag assigment reset: set True to reset already set up tag details (bool): set False if tag should be added for list selection, default is details page """ if details: view = navigate_to(self, 'EditTagsFromDetails') else: view = navigate_to(self, 'EditTags') if not tag: tag = self._set_random_tag(view) category_name = tag.category.display_name tag_name = tag.display_name # Handle nested view.form and where the view contains form widgets try: updated = view.form.fill({ "tag_category": '{} *'.format(category_name), "tag_name": tag_name }) except (NoSuchElementException, SelectItemNotFound): updated = view.form.fill({ "tag_category": category_name, "tag_name": tag_name }) # In case if field is not updated cancel the edition if not updated: cancel = True self._tags_action(view, cancel, reset) return tag
def prerequisite(self): try: view = navigate_to(self.obj, 'All') except NavigationDestinationNotFound: view = navigate_to(self.obj.parent, 'All') finally: return view
def test_infrastructurehost_defaultfilters(appliance): filters = [['Infrastructure', 'Hosts', 'Platform / HyperV']] df = st.DefaultFilter(name='Platform / HyperV') df.update({'filters': [(k, True) for k in filters]}) host_collecton = appliance.collections.hosts navigate_to(host_collecton, 'All') assert sel.is_displayed_text(df.name), "Default Filter settings Failed!"
def test_ansible_playbook_button_crud(ansible_catalog_item, appliance, request): """ Polarion: assignee: sbulage casecomponent: Ansible caseimportance: medium initialEstimate: 1/6h """ buttongroup = appliance.collections.button_groups.create( text=fauxfactory.gen_alphanumeric(), hover=fauxfactory.gen_alphanumeric(), type=appliance.collections.button_groups.VM_INSTANCE) request.addfinalizer(buttongroup.delete_if_exists) button = buttongroup.buttons.create( type='Ansible Playbook', text=fauxfactory.gen_alphanumeric(), hover=fauxfactory.gen_alphanumeric(), playbook_cat_item=ansible_catalog_item.name) request.addfinalizer(button.delete_if_exists) assert button.exists view = navigate_to(button, 'Details') assert view.text.text == button.text assert view.hover.text == button.hover edited_hover = "edited {}".format(fauxfactory.gen_alphanumeric()) with update(button): button.hover = edited_hover assert button.exists view = navigate_to(button, 'Details') assert view.hover.text == edited_hover button.delete(cancel=True) assert button.exists button.delete() assert not button.exists
def test_permission_edit(appliance, request, product_features): """ Ensures that changes in permissions are enforced on next login by attempting to navigate to a page with and without permissions to access that page Args: appliance: cfme appliance fixture request: pytest request fixture product_features: product features to set for test role action: reference to a function to execute under the test user context """ role_name = fauxfactory.gen_alphanumeric() role = appliance.collections.roles.create(name=role_name, vm_restriction=None, product_features=[(['Everything'], False)] + # role_features [(k, True) for k in product_features]) group_description = 'grp{}'.format(fauxfactory.gen_alphanumeric()) group = group_collection(appliance).create(description=group_description, role=role.name) user = new_user(appliance, [group]) with user: # Navigation should succeed with valid permissions navigate_to(appliance.collections.infra_vms, 'VMsOnly') appliance.server.login_admin() role.update({'product_features': [(['Everything'], True)] + [(k, False) for k in product_features] }) with user: with pytest.raises(Exception, message='Permissions have not been updated'): navigate_to(appliance.collections.infra_vms, 'VMsOnly') @request.addfinalizer def _delete_user_group_role(): for item in [user, group, role]: item.delete()
def _check_item_visibility(vis_object, vis_expect): """ Args: vis_object: the object with a tag to check vis_expect: bool, True if tag should be visible Returns: None """ if vis_expect: vis_object.add_tag(tag=tag) else: tags = vis_object.get_tags() tag_assigned = any( object_tags.category.display_name == tag.category.display_name and object_tags.display_name == tag.display_name for object_tags in tags ) if tag_assigned: vis_object.remove_tag(tag=tag) with user_restricted: try: navigate_to(vis_object, 'Details') actual_visibility = True except Exception: logger.debug('Tagged item is not visible') actual_visibility = False assert actual_visibility == vis_expect
def reconfigure_service(self): view = navigate_to(self, 'Reconfigure') view.submit_button.click() view = self.create_view(RequestsView) assert view.is_displayed view.flash.assert_no_error()
def exists(self): try: navigate_to(self, 'Details') except CandidateNotFound: return False return True
def test_custom_button_expression(appliance, request, setup_obj, button_group, expression): """ Test custom button as per expression enablement/visibility. Polarion: assignee: ndhandre initialEstimate: 1/4h caseimportance: medium caseposneg: positive testtype: functional startsin: 5.9 casecomponent: CustomButton tags: custom_button testSteps: 1. Create custom button group with the Object type 2. Create a custom button with expression (Tag) a. Enablement Expression b. Visibility Expression 3. Navigate to object Detail page 4. Check: button should not enable/visible without tag 5. Check: button should enable/visible with tag """ group, obj_type = button_group exp = { expression: { "tag": "My Company Tags : Department", "value": "Engineering" } } button = group.buttons.create(text=fauxfactory.gen_alphanumeric(), hover=fauxfactory.gen_alphanumeric(), display_for="Single entity", system="Request", request="InspectMe", **exp) request.addfinalizer(button.delete_if_exists) tag_cat = appliance.collections.categories.instantiate( name="department", display_name="Department") tag = tag_cat.collections.tags.instantiate(name="engineering", display_name="Engineering") view = navigate_to(setup_obj, "Details") custom_button_group = Dropdown(view, group.hover) if tag.display_name in [ item.display_name for item in setup_obj.get_tags() ]: if expression == "enablement": assert custom_button_group.item_enabled(button.text) setup_obj.remove_tag(tag) assert not custom_button_group.is_enabled elif expression == "visibility": assert button.text in custom_button_group.items setup_obj.remove_tag(tag) assert not custom_button_group.is_displayed else: if expression == "enablement": assert not custom_button_group.is_enabled setup_obj.add_tag(tag) assert custom_button_group.item_enabled(button.text) elif expression == "visibility": assert not custom_button_group.is_displayed setup_obj.add_tag(tag) assert button.text in custom_button_group.items
def test_custom_button_dialog(appliance, dialog, request, setup_obj, button_group): """ Test custom button with dialog and InspectMe method Polarion: assignee: ndhandre initialEstimate: 1/4h caseimportance: high caseposneg: positive testtype: functional startsin: 5.10 casecomponent: CustomButton tags: custom_button testSteps: 1. Create custom button group with the Object type 2. Create a custom button with service dialog 3. Navigate to object Details page 4. Check for button group and button 5. Select/execute button from group dropdown for selected entities 6. Fill dialog and submit 7. Check for the proper flash message related to button execution 8. Check request in automation log """ group, obj_type = button_group # Note: No need to set display_for dialog only work with Single entity button = group.buttons.create( text=fauxfactory.gen_alphanumeric(), hover=fauxfactory.gen_alphanumeric(), dialog=dialog, system="Request", request="InspectMe", ) request.addfinalizer(button.delete_if_exists) view = navigate_to(setup_obj, "Details") custom_button_group = Dropdown(view, group.hover) assert custom_button_group.has_item(button.text) custom_button_group.item_select(button.text) dialog_view = view.browser.create_view(TextInputDialogView, wait="10s") assert dialog_view.service_name.fill("Custom Button Execute") # Clear the automation log assert appliance.ssh_client.run_command( 'echo -n "" > /var/www/miq/vmdb/log/automation.log') # Submit order dialog_view.submit.click() view.wait_displayed("60s") view.flash.assert_message("Order Request was Submitted") # Check for request in automation log try: wait_for( log_request_check, [appliance, 1], timeout=300, message="Check for expected request count", delay=20, ) except TimedOutError: assert False, "Expected 1 requests not found in automation log"
def test_custom_button_automate(appliance, request, submit, setup_obj, button_group): """ Test custom button for automate and requests count as per submit Polarion: assignee: ndhandre initialEstimate: 1/4h caseimportance: high caseposneg: positive testtype: functional startsin: 5.10 casecomponent: CustomButton tags: custom_button testSteps: 1. Create custom button group with the Object type 2. Create a custom button with specific submit option and Single and list display 3. Navigate to object type pages (All and Details) 4. Check for button group and button 5. Select/execute button from group dropdown for selected entities 6. Check for the proper flash message related to button execution 7. Check automation log requests. Submitted as per selected submit option or not. 8. Submit all: single request for all entities execution 9. One by one: separate requests for all entities execution Bugzilla: 1628224, 1642939 """ group, obj_type = button_group button = group.buttons.create( text=fauxfactory.gen_alphanumeric(), hover=fauxfactory.gen_alphanumeric(), display_for="Single and list", submit=submit, system="Request", request="InspectMe", ) request.addfinalizer(button.delete_if_exists) for destination in ["All", "Details"]: obj = setup_obj.parent if destination == "All" else setup_obj view = navigate_to(obj, destination) custom_button_group = Dropdown(view, group.hover) assert custom_button_group.has_item(button.text) # Entity count depends on the destination for `All` available entities and # `Details` means a single entity. if destination == "All": entity_count = min(view.paginator.items_amount, view.paginator.items_per_page) view.paginator.check_all() else: entity_count = 1 # Clear the automation log assert appliance.ssh_client.run_command( 'echo -n "" > /var/www/miq/vmdb/log/automation.log') custom_button_group.item_select(button.text) view.flash.assert_message('"{}" was executed'.format(button.text)) # Submit all: single request for all entity execution # One by one: separate requests for all entity execution expected_count = 1 if submit == "Submit all" else entity_count try: wait_for( log_request_check, [appliance, expected_count], timeout=120, message="Check for expected request count", delay=10, ) except TimedOutError: assert False, "Expected {} requests not found in automation log".format( str(expected_count))
def test_group_roles(appliance, setup_aws_auth_provider, group_name, role_access, context, soft_assert): """Basic default AWS_IAM group role auth + RBAC test Validates expected menu and submenu names are present for default AWS IAM groups NOTE: Only tests vertical navigation tree at the moment, not accordions within the page """ group_access = role_access[group_name] try: iam_group_name = group_name + '_aws_iam' username = credentials[iam_group_name]['username'] password = credentials[iam_group_name]['password'] fullname = credentials[iam_group_name]['fullname'] except KeyError: pytest.fail('No match in credentials file for group "{}"'.format( iam_group_name)) with appliance.context.use(context): # fullname overrides user.name attribute, but doesn't impact login with username credential user = appliance.collections.users.simple_user(username, password, fullname=fullname) with user: view = navigate_to(appliance.server, 'LoggedIn', wait_for_view=True) assert appliance.server.current_full_name() == user.name assert group_name.lower() in [ name.lower() for name in appliance.server.group_names() ] nav_visible = view.navigation.nav_item_tree() # RFE BZ 1526495 shows up as an extra requests link in nav # TODO BZ remove assert skip when BZ is fixed in 59z bz = BZ( 1526495, forced_streams=['5.8', '5.9'], unblock=lambda group_name: group_name not in [ 'evmgroup-user', 'evmgroup-approver', 'evmgroup-desktop', 'evmgroup-vm_user', 'evmgroup-administrator', 'evmgroup-super_administrator' ]) for area in group_access.keys(): # using .get() on nav_visibility because it may not have `area` key diff = DeepDiff( group_access[area], nav_visible.get(area, {}), verbose_level= 0, # If any higher, will flag string vs unicode ignore_order=True) nav_extra = diff.get('iterable_item_added') if nav_extra and 'Requests' in nav_extra.values( ) and bz.blocks: logger.warning( 'Skipping RBAC verification for group "%s" in "%s" due to %r', group_name, area, bz) continue else: soft_assert( diff == {}, '{g} RBAC mismatch (expected first) for {a}: {d}'. format(g=group_name, a=area, d=diff)) appliance.server.login_admin() assert user.exists
def test_node_memory(provider): view_details = navigate_to(provider, 'Details') node_memory = view_details.entities.summary('Properties').get_text_of( 'Aggregate Node Memory') assert float(node_memory.split()[0]) > 0
def check_vm_add(self, add_vm_name): view = navigate_to(self, 'Details') view.entities.get_entity(name=add_vm_name).click() view.flash.assert_no_error()
def prerequisite(self, *args, **kwargs): return navigate_to( self.obj.parent, 'AllForProvider' if self.obj.parent.filters.get('provider') else 'All')
def download_file(self, extension): view = navigate_to(self, 'All') view.download_choice.item_select("Download as {}".format(extension)) view.flash.assert_no_error()
def _remove_docker_creds(): view = navigate_to(provider, "Edit") ssa_agent_view = view.browser.create_view(EC2EndpointForm) ssa_agent_view.smart_state_docker.fill({'username': ""}) ssa_agent_view.smart_state_docker.change_pass.click() view.save.click()
def prerequisite(self): provider = self.obj.filters.get("provider") if provider: return navigate_to(provider, "Instances") else: return navigate_to(self.obj, "All")
def identify_led_state(self): view = navigate_to(self, "Details") return view.entities.summary("Properties").get_text_of( "Identify LED State")
def test_drift_analysis(request, ssa_vm, soft_assert, appliance): """ Tests drift analysis is correct Metadata: test_flag: vm_analysis """ ssa_vm.load_details() drift_num_orig = 0 view = navigate_to(ssa_vm, "Details") drift_orig = view.entities.summary("Relationships").get_text_of( "Drift History") if drift_orig != 'None': drift_num_orig = int(drift_orig) ssa_vm.smartstate_scan(wait_for_task_result=True) view = navigate_to(ssa_vm, "Details") wait_for(lambda: view.entities.summary("Relationships").get_text_of( "Drift History") == str(drift_num_orig + 1), delay=20, num_sec=360, message="Waiting for Drift History count to increase", fail_func=view.toolbar.reload.click) drift_new = int( view.entities.summary("Relationships").get_text_of("Drift History")) # add a tag and a finalizer to remove it added_tag = appliance.collections.categories.instantiate( display_name='Department').collections.tags.instantiate( display_name='Accounting') ssa_vm.add_tag(added_tag) request.addfinalizer(lambda: ssa_vm.remove_tag(added_tag)) ssa_vm.smartstate_scan(wait_for_task_result=True) view = navigate_to(ssa_vm, "Details") wait_for(lambda: view.entities.summary("Relationships").get_text_of( "Drift History") == str(drift_new + 1), delay=20, num_sec=360, message="Waiting for Drift History count to increase", fail_func=view.toolbar.reload.click) # check drift difference soft_assert( ssa_vm.equal_drift_results( '{} (1)'.format(added_tag.category.display_name), 'My Company Tags', 1, 2), "Drift analysis results are equal when they shouldn't be") # Test UI features that modify the drift grid drift_analysis_view = appliance.browser.create_view(DriftAnalysis) # Accounting tag should not be displayed, because it was changed to True drift_analysis_view.toolbar.same_values_attributes.click() soft_assert( not drift_analysis_view.drift_analysis. check_section_attribute_availability('{}'.format( added_tag.category.display_name)), "{} row should be hidden, but not".format(added_tag.display_name)) # Accounting tag should be displayed now drift_analysis_view.toolbar.different_values_attributes.click() soft_assert( drift_analysis_view.drift_analysis. check_section_attribute_availability('{} (1)'.format( added_tag.category.display_name)), "{} row should be visible, but not".format(added_tag.display_name))
def chassis_name(self): view = navigate_to(self, "Details") return view.entities.summary("Properties").get_text_of("Chassis name")
def num_physical_servers(self): view = navigate_to(self, "Details") return view.entities.summary("Relationships").get_text_of( "Physical Servers")
def load_details(self, refresh=False): navigate_to(self, 'Details') if refresh: tb.refresh()
def description(self): view = navigate_to(self, "Details") return view.entities.summary("Properties").get_text_of("Description")
def valid_credentials_state(self): """ Checks whether credentials are valid """ view = navigate_to(self, 'Details') cred_state = view.entities.status.get_text_of('Default Credentials') return cred_state == "Valid"
def _execute_button(self, button, option, handle_alert=False): view = navigate_to(self, "Details") view.toolbar.custom_button(button).item_select( option, handle_alert=handle_alert) return view
def all(self): view = navigate_to(self, 'All') list_networks = view.entities.get_all(surf_pages=True) return [self.instantiate(name=p.name) for p in list_networks]
def test_vm_retire_extend(appliance, request, create_vm, soft_assert): """ Tests extending a retirement using an AE method. Polarion: assignee: ghubale casecomponent: Automate initialEstimate: 1/3h setup: 1. A running VM on any provider. testSteps: 1. It creates a button pointing to ``Request/vm_retire_extend`` instance. The button should live in the VM and Instance button group. 2. Then it sets a retirement date for the VM 3. Then it waits until the retirement date is set 4. Then it clicks the button that was created and it waits for the retirement date to extend. Bugzilla: 1627758 """ num_days = 5 soft_assert(create_vm.retirement_date == 'Never', "The retirement date is not 'Never'!") retirement_date = generate_retirement_date(delta=num_days) create_vm.set_retirement_date(retirement_date) wait_for(lambda: create_vm.retirement_date != 'Never', message="retirement date set") set_date = create_vm.retirement_date vm_retire_date_fmt = create_vm.RETIRE_DATE_FMT soft_assert( set_date == retirement_date.strftime(vm_retire_date_fmt), "The retirement date '{}' did not match expected date '{}'".format( set_date, retirement_date.strftime(vm_retire_date_fmt))) # Create the vm_retire_extend button and click on it grp_name = fauxfactory.gen_alphanumeric(start="grp_") grp = appliance.collections.button_groups.create( text=grp_name, hover=grp_name, type=appliance.collections.button_groups.VM_INSTANCE) request.addfinalizer(lambda: grp.delete_if_exists()) btn_name = fauxfactory.gen_alphanumeric(start="btn_") button = grp.buttons.create(text=btn_name, hover=btn_name, system="Request", request="vm_retire_extend") request.addfinalizer(lambda: button.delete_if_exists()) navigate_to(create_vm, 'Details') class TestDropdownView(InfraVmSummaryView): group = Dropdown(grp.text) view = appliance.browser.create_view(TestDropdownView) view.group.item_select(button.text) # CFME automate vm_retire_extend method defaults to extending the date by 14 days extend_duration_days = 14 extended_retirement_date = retirement_date + timedelta( days=extend_duration_days) # Check that the WebUI updates with the correct date wait_for( lambda: create_vm.retirement_date >= extended_retirement_date.strftime( vm_retire_date_fmt), num_sec=60, message="Check for extension of the VM retirement date by {} days". format(extend_duration_days))
def update_ui(self): view = navigate_to(self.parent, 'All') view.toolbar.reload.click() self.row = view.find_request(cells=self.cells, partial_check=self.partial_check)
def refresh_provider_relationships(self, cancel=True): """ Refresh relationships of network provider """ view = navigate_to(self, 'Details') view.toolbar.configuration.item_select( 'Refresh Relationships and Power States', handle_alert=not cancel)
def get_all_providers(): """Returns list of all providers""" view = navigate_to(InfraProvider, 'All') return [item.name for item in view.entities.get_all(surf_pages=True)]
def get_request_row_from_ui(self): """Opens CFME UI and return table_row object""" view = navigate_to(self.parent, 'All') self.row = view.find_request(self.cells, partial_check=self.partial_check) return self.row
def scale_down(self): """Scales down provider""" view = navigate_to(self, 'ScaleDown') view.checkbox.click() view.scale_down.click() self.create_view(ProviderNodesView).flash.assert_no_error()
def test_control_is_ansible_playbook_available_in_actions_dropdown( action_collection): view = navigate_to(action_collection, "Add") assert "Run Ansible Playbook" in [ option.text for option in view.action_type.all_options ]
def rack_name(self): view = navigate_to(self, "Details") return view.entities.properties.get_text_of("Rack name")
def test_provisioning_dialogs_sorting(appliance, name, by, order): view = navigate_to(appliance.collections.provisioning_dialogs, 'All') view.sidebar.provisioning_dialogs.tree.click_path("All Dialogs", name) view.entities.table.sort_by(by, order)