From 74458f145766a88e1f15a70e207f59ad4716b1f5 Mon Sep 17 00:00:00 2001 From: Ganesh Hubale Date: Tue, 28 May 2019 19:29:45 +0530 Subject: [PATCH 1/2] Adding CRUD operations for automate method --- cfme/automate/explorer/method.py | 88 +++++++++++++++++++++--------- cfme/tests/automate/test_method.py | 44 +++++++++++---- 2 files changed, 95 insertions(+), 37 deletions(-) diff --git a/cfme/automate/explorer/method.py b/cfme/automate/explorer/method.py index 2b6f4f84f7..55c3a60a5c 100644 --- a/cfme/automate/explorer/method.py +++ b/cfme/automate/explorer/method.py @@ -27,7 +27,6 @@ from cfme.utils.appliance.implementations.ui import CFMENavigateStep from cfme.utils.appliance.implementations.ui import navigate_to from cfme.utils.appliance.implementations.ui import navigator -from cfme.utils.blockers import BZ from cfme.utils.timeutil import parsetime from cfme.utils.wait import wait_for from widgetastic_manageiq import EntryPoint @@ -239,6 +238,7 @@ class MethodAddView(AutomateExplorerView): location = BootstrapSelect('cls_method_location', can_hide_on_select=True) + # Inline inline_name = Input(name='cls_method_name') inline_display_name = Input(name='cls_method_display_name') script = ScriptBox() @@ -246,6 +246,7 @@ class MethodAddView(AutomateExplorerView): validate_button = Button('Validate') inputs = View.nested(Inputs) + # Playbook playbook_name = Input(name='name') playbook_display_name = Input(name='display_name') repository = PlaybookBootstrapSelect('provisioning_repository_id') @@ -263,6 +264,16 @@ class MethodAddView(AutomateExplorerView): embedded_method = EntryPoint(locator='//*[@id="automate-inline-method-select"]//button', tree_id="treeview-entrypoint_selection") + # Ansible Tower Workflow Template + ansible_tower_workflow_template_name = Input(name="name") + ansible_tower_workflow_template_display_name = Input(name="display_name") + + # Ansible Tower Job Template + ansible_tower_job_template_name = Input(name="name") + ansible_tower_job_template_display_name = Input(name="display_name") + + ansible_max_ttl = Input(name='provisioning_execution_ttl') + add_button = Button('Add') cancel_button = Button('Cancel') @@ -306,30 +317,41 @@ class MethodEditView(AutomateExplorerView): embedded_method = EntryPoint(locator='//*[@id="automate-inline-method-select"]//button', tree_id="treeview-entrypoint_selection") + # Ansible Tower Workflow Template + ansible_tower_workflow_template_name = Input(name="name") + ansible_tower_workflow_template_display_name = Input(name="display_name") + + # Ansible Tower Job Template + ansible_tower_job_template_name = Input(name="name") + ansible_tower_job_template_display_name = Input(name="display_name") + + ansible_max_ttl = Input(name='provisioning_execution_ttl') + save_button = Button('Save') reset_button = Button('Reset') cancel_button = Button('Cancel') def before_fill(self, values): location = self.context['object'].location.lower() - if 'display_name' in values and location in ['inline', 'playbook']: - values['{}_display_name'.format(location)] = values['display_name'] + if 'display_name' in values and location in ['inline', 'playbook', + 'ansible tower job template', + 'ansible tower workflow template']: + values['{}_display_name'.format(location.replace(" ", "_"))] = values['display_name'] del values['display_name'] - elif 'name' in values and location in ['inline', 'playbook']: - values['{}_name'.format(location)] = values['name'] + elif 'name' in values and location in ['inline', 'playbook', 'ansible tower job template', + 'ansible tower workflow template']: + values['{}_name'.format(location.replace(" ", "_"))] = values['name'] del values['name'] @property def is_displayed(self): return ( - self.in_explorer - and self.datastore.is_opened - and (f'Editing Automate Method "{self.context["object"].name}"' in self.title.text) + self.in_explorer and + self.datastore.is_opened and + 'Editing Automate Method "{}"'.format(self.context['object'].name) in self.title.text and check_tree_path( self.datastore.tree.currently_selected, - self.context["object"].tree_path, - partial=True, - ) + self.context['object'].tree_path, partial=True) ) @@ -401,11 +423,18 @@ def domain(self): def tree_path(self): icon_name_map = {'inline': 'fa-ruby', 'playbook': 'vendor-ansible'} if self.display_name: - return self.parent_obj.tree_path + [ - (icon_name_map[self.location.lower()], '{} ({})'.format(self.display_name, - self.name))] + if self.location in ['Ansible Tower Job Template', 'Ansible Tower Workflow Template']: + return self.parent_obj.tree_path + [f'{self.display_name} ({self.name})'] + else: + return self.parent_obj.tree_path + [ + (icon_name_map[self.location.lower()], f'{self.display_name} ({self.name})')] else: - return self.parent_obj.tree_path + [(icon_name_map[self.location.lower()], self.name)] + if self.location in ['Ansible Tower Job Template', 'Ansible Tower Workflow Template']: + return self.parent_obj.tree_path + [self.name] + else: + return self.parent_obj.tree_path + [( + icon_name_map[self.location.lower()], self.name + )] @property def tree_path_name_only(self): @@ -484,6 +513,25 @@ def create( 'playbook_input_parameters': playbook_input_parameters }) validate = False + + if location == 'Ansible Tower Workflow Template': + add_page.wait_displayed() + add_page.fill({ + 'ansible_tower_workflow_template_name': name, + 'ansible_tower_workflow_template_display_name': display_name, + 'ansible_max_ttl': max_ttl, + }) + validate = False + + if location == 'Ansible Tower Job Template': + add_page.wait_displayed() + add_page.fill({ + 'ansible_tower_job_template_name': name, + 'ansible_tower_job_template_display_name': display_name, + 'ansible_max_ttl': max_ttl, + }) + validate = False + if validate: add_page.validate_button.click() add_page.wait_displayed() @@ -499,12 +547,6 @@ def create( add_page.add_button.click() add_page.flash.assert_no_error() - # TODO(BZ-1704439): Remove the work-around once this BZ got fixed - if BZ(1704439).blocks: - view = self.create_view(ClassDetailsView) - view.flash.assert_message('Automate Method "{}" was added'.format(name)) - self.browser.refresh() - return self.instantiate( name=name, display_name=display_name, @@ -558,10 +600,6 @@ def delete(self, *methods): all_page.flash.assert_message( 'Automate Method "{}": Delete successful'.format(method.name)) - # TODO(BZ-1704439): Remove the work-around once this BZ got fixed - if BZ(1704439).blocks: - self.browser.refresh() - @navigator.register(MethodCollection) class Add(CFMENavigateStep): diff --git a/cfme/tests/automate/test_method.py b/cfme/tests/automate/test_method.py index 46b20618c9..e593374862 100644 --- a/cfme/tests/automate/test_method.py +++ b/cfme/tests/automate/test_method.py @@ -12,7 +12,6 @@ from cfme.utils.appliance.implementations.rest import ViaREST from cfme.utils.appliance.implementations.ui import navigate_to from cfme.utils.appliance.implementations.ui import ViaUI -from cfme.utils.blockers import BZ from cfme.utils.log_validator import FailPatternMatchError from cfme.utils.log_validator import LogValidator from cfme.utils.update import update @@ -32,8 +31,20 @@ def original_class(domain): @pytest.mark.sauce -def test_method_crud(klass): +@pytest.mark.meta(automates=[1704439]) +@pytest.mark.parametrize( + "method_type", ["inline", "Ansible Tower Job Template", "Ansible Tower Workflow Template"] +) +@pytest.mark.uncollectif( + lambda method_type, appliance: method_type + in ("Ansible Tower Job Template", "Ansible Tower Workflow Template") + and appliance.version < 5.11 +) +def test_method_crud(method_type, klass): """ + Bugzilla: + 1704439 + Polarion: assignee: ghubale casecomponent: Automate @@ -42,21 +53,30 @@ def test_method_crud(klass): tags: automate """ # TODO(ghubale@redhat.com): Update this test case for other types of automate methods like - # builtin, expression, uri, playbook, Ansible Tower Job Template and Ansible Tower Workflow - # Template - method = klass.methods.create( - name=fauxfactory.gen_alphanumeric(), - display_name=fauxfactory.gen_alphanumeric(), - location='inline', - script='$evm.log(:info, ":P")', - ) + # builtin, expression, uri, playbook + if method_type in ['Ansible Tower Job Template', 'Ansible Tower Workflow Template']: + method = klass.methods.create( + name=fauxfactory.gen_alphanumeric(), + display_name=fauxfactory.gen_alphanumeric(), + location=method_type, + max_ttl='2' + ) + elif method_type == 'inline': + method = klass.methods.create( + name=fauxfactory.gen_alphanumeric(), + display_name=fauxfactory.gen_alphanumeric(), + location=method_type, + script='$evm.log(:info, ":P")', + ) view = method.create_view(ClassDetailsView) - view.flash.assert_message(f'Automate Method "{method.name}" was added') + if method_type in ['Ansible Tower Job Template', 'Ansible Tower Workflow Template']: + view.flash.assert_message(f'Automate Method "{method.name}" was saved') + else: + view.flash.assert_message(f'Automate Method "{method.name}" was added') assert method.exists origname = method.name with update(method): method.name = fauxfactory.gen_alphanumeric(8) - method.script = "bar" assert method.exists with update(method): method.name = origname From 554ce24562b1b1ce7d323dab85fa14586bebc038 Mon Sep 17 00:00:00 2001 From: Ganesh Hubale Date: Fri, 13 Sep 2019 16:24:48 +0530 Subject: [PATCH 2/2] updated with requested changes Signed-off-by: Ganesh Hubale --- cfme/automate/explorer/method.py | 78 ++++++++++++------------------ cfme/tests/automate/test_method.py | 9 ++-- 2 files changed, 37 insertions(+), 50 deletions(-) diff --git a/cfme/automate/explorer/method.py b/cfme/automate/explorer/method.py index 55c3a60a5c..b5a34a9569 100644 --- a/cfme/automate/explorer/method.py +++ b/cfme/automate/explorer/method.py @@ -233,7 +233,7 @@ def read(self): class MethodAddView(AutomateExplorerView): - fill_strategy = WaitFillViewStrategy() + fill_strategy = WaitFillViewStrategy("20s") title = Text('#explorer_title_text') location = BootstrapSelect('cls_method_location', can_hide_on_select=True) @@ -246,9 +246,10 @@ class MethodAddView(AutomateExplorerView): validate_button = Button('Validate') inputs = View.nested(Inputs) - # Playbook - playbook_name = Input(name='name') - playbook_display_name = Input(name='display_name') + # Playbook, Ansible Tower Workflow Template, Ansible Tower Job Template + method_name = Input(name='name') + method_display_name = Input(name='display_name') + repository = PlaybookBootstrapSelect('provisioning_repository_id') playbook = PlaybookBootstrapSelect('provisioning_playbook_id') machine_credential = PlaybookBootstrapSelect('provisioning_machine_credential_id') @@ -264,14 +265,6 @@ class MethodAddView(AutomateExplorerView): embedded_method = EntryPoint(locator='//*[@id="automate-inline-method-select"]//button', tree_id="treeview-entrypoint_selection") - # Ansible Tower Workflow Template - ansible_tower_workflow_template_name = Input(name="name") - ansible_tower_workflow_template_display_name = Input(name="display_name") - - # Ansible Tower Job Template - ansible_tower_job_template_name = Input(name="name") - ansible_tower_job_template_display_name = Input(name="display_name") - ansible_max_ttl = Input(name='provisioning_execution_ttl') add_button = Button('Add') @@ -289,6 +282,7 @@ def is_displayed(self): class MethodEditView(AutomateExplorerView): + fill_strategy = WaitFillViewStrategy("20s") title = Text('#explorer_title_text') # inline @@ -299,9 +293,10 @@ class MethodEditView(AutomateExplorerView): validate_button = Button('Validate') inputs = View.nested(Inputs) - # playbook - playbook_name = Input(name='name') - playbook_display_name = Input(name='display_name') + # Playbook, Ansible Tower Workflow Template, Ansible Tower Job Template + method_name = Input(name='name') + method_display_name = Input(name='display_name') + repository = PlaybookBootstrapSelect('provisioning_repository_id') playbook = PlaybookBootstrapSelect('provisioning_playbook_id') machine_credential = PlaybookBootstrapSelect('provisioning_machine_credential_id') @@ -317,14 +312,6 @@ class MethodEditView(AutomateExplorerView): embedded_method = EntryPoint(locator='//*[@id="automate-inline-method-select"]//button', tree_id="treeview-entrypoint_selection") - # Ansible Tower Workflow Template - ansible_tower_workflow_template_name = Input(name="name") - ansible_tower_workflow_template_display_name = Input(name="display_name") - - # Ansible Tower Job Template - ansible_tower_job_template_name = Input(name="name") - ansible_tower_job_template_display_name = Input(name="display_name") - ansible_max_ttl = Input(name='provisioning_execution_ttl') save_button = Button('Save') @@ -333,14 +320,18 @@ class MethodEditView(AutomateExplorerView): def before_fill(self, values): location = self.context['object'].location.lower() - if 'display_name' in values and location in ['inline', 'playbook', - 'ansible tower job template', - 'ansible tower workflow template']: - values['{}_display_name'.format(location.replace(" ", "_"))] = values['display_name'] + if 'display_name' in values: + if location == 'inline': + values[f'{location}_display_name'] = values['display_name'] + else: + values['method_display_name'] = values['display_name'] del values['display_name'] - elif 'name' in values and location in ['inline', 'playbook', 'ansible tower job template', - 'ansible tower workflow template']: - values['{}_name'.format(location.replace(" ", "_"))] = values['name'] + + elif 'name' in values: + if location == 'inline': + values[f'{location.replace(" ", "_")}_name'] = values['name'] + else: + values['method_name'] = values['name'] del values['name'] @property @@ -357,6 +348,8 @@ def is_displayed(self): class Method(BaseEntity, Copiable): + LOCATIONS = ['Ansible Tower Job Template', 'Ansible Tower Workflow Template'] + def __init__(self, collection, name=None, display_name=None, location='inline', script=None, data=None, repository=None, playbook=None, machine_credential=None, hosts=None, max_ttl=None, logging_output=None, escalate_privilege=None, verbosity=None, @@ -423,13 +416,13 @@ def domain(self): def tree_path(self): icon_name_map = {'inline': 'fa-ruby', 'playbook': 'vendor-ansible'} if self.display_name: - if self.location in ['Ansible Tower Job Template', 'Ansible Tower Workflow Template']: + if self.location in self.LOCATIONS: return self.parent_obj.tree_path + [f'{self.display_name} ({self.name})'] else: return self.parent_obj.tree_path + [ (icon_name_map[self.location.lower()], f'{self.display_name} ({self.name})')] else: - if self.location in ['Ansible Tower Job Template', 'Ansible Tower Workflow Template']: + if self.location in self.LOCATIONS: return self.parent_obj.tree_path + [self.name] else: return self.parent_obj.tree_path + [( @@ -481,6 +474,7 @@ def create( playbook_input_parameters=None, inputs=None, embedded_method=None): add_page = navigate_to(self, 'Add') + add_page.wait_displayed("25s") if self.browser.product_version > '5.11' and location.islower(): location = location.capitalize() @@ -497,8 +491,8 @@ def create( }) if location.lower() == 'playbook': add_page.fill({ - 'playbook_name': name, - 'playbook_display_name': display_name, + 'method_name': name, + 'method_display_name': display_name, 'repository': repository }) wait_for(lambda: add_page.playbook.is_displayed, delay=0.5, num_sec=2) @@ -514,20 +508,10 @@ def create( }) validate = False - if location == 'Ansible Tower Workflow Template': - add_page.wait_displayed() - add_page.fill({ - 'ansible_tower_workflow_template_name': name, - 'ansible_tower_workflow_template_display_name': display_name, - 'ansible_max_ttl': max_ttl, - }) - validate = False - - if location == 'Ansible Tower Job Template': - add_page.wait_displayed() + if location in ['Ansible Tower Workflow Template', 'Ansible Tower Job Template']: add_page.fill({ - 'ansible_tower_job_template_name': name, - 'ansible_tower_job_template_display_name': display_name, + 'method_name': name, + 'method_display_name': display_name, 'ansible_max_ttl': max_ttl, }) validate = False diff --git a/cfme/tests/automate/test_method.py b/cfme/tests/automate/test_method.py index e593374862..60c982c887 100644 --- a/cfme/tests/automate/test_method.py +++ b/cfme/tests/automate/test_method.py @@ -12,6 +12,7 @@ from cfme.utils.appliance.implementations.rest import ViaREST from cfme.utils.appliance.implementations.ui import navigate_to from cfme.utils.appliance.implementations.ui import ViaUI +from cfme.utils.blockers import BZ from cfme.utils.log_validator import FailPatternMatchError from cfme.utils.log_validator import LogValidator from cfme.utils.update import update @@ -31,19 +32,21 @@ def original_class(domain): @pytest.mark.sauce -@pytest.mark.meta(automates=[1704439]) +@pytest.mark.meta(automates=[1704439, 1591797]) @pytest.mark.parametrize( - "method_type", ["inline", "Ansible Tower Job Template", "Ansible Tower Workflow Template"] + "method_type", ["inline", "Ansible Tower Job Template", "Ansible Tower Workflow Template"], + ids=["inline", "job", "workflow"] ) @pytest.mark.uncollectif( lambda method_type, appliance: method_type in ("Ansible Tower Job Template", "Ansible Tower Workflow Template") - and appliance.version < 5.11 + and appliance.version < 5.11, reason="These type of methods introduced in 5.11" ) def test_method_crud(method_type, klass): """ Bugzilla: 1704439 + 1591797 Polarion: assignee: ghubale