Repository: ManageIQ/integration_tests

Issue:
ImportError in cfme/infrastructure/test_host.py
PR #4905 removed credential_form from cfme.infrastructure.host, resulting in an ImportError on test setup.

```ImportError while importing test module '/home/mshriver/repos/integration_tests/cfme/tests/infrastructure/test_host.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
cfme/tests/infrastructure/test_host.py:6: in <module>
    from cfme.infrastructure.host import credential_form
E   ImportError: cannot import name credential_form
```


Discussion:

Resolving patch:
diff --git a/cfme/common/host_views.py b/cfme/common/host_views.py
--- a/cfme/common/host_views.py
+++ b/cfme/common/host_views.py
@@ -299,6 +299,7 @@ def is_displayed(self):
 
 
 class HostEditView(HostFormView):
+    """View for editing a single host"""
     save_button = Button("Save")
     reset_button = Button("Reset")
     change_stored_password = Text(".//a[contains(@ng-hide, 'bChangeStoredPassword')]")
@@ -306,3 +307,16 @@ class HostEditView(HostFormView):
     @property
     def is_displayed(self):
         return self.in_compute_infrastructure_hosts and self.title.text == "Info/Settings"
+
+
+class HostsEditView(HostEditView):
+    """View when editing multiple hosts
+        Restricted to endpoints section of the form
+        Title changes
+        Must select host before validation
+    """
+    validation_host = BootstrapSelect('validate_id')  # only shown when editing multiple hosts
+
+    @property
+    def is_displayed(self):
+        return self.in_compute_infrastructure_hosts and self.title.text == 'Credentials/Settings'
diff --git a/cfme/infrastructure/provider/virtualcenter.py b/cfme/infrastructure/provider/virtualcenter.py
--- a/cfme/infrastructure/provider/virtualcenter.py
+++ b/cfme/infrastructure/provider/virtualcenter.py
@@ -1,6 +1,11 @@
+from navmazing import NavigateToSibling
+from wrapanapi.virtualcenter import VMWareSystem
+
 from cfme.common.provider import DefaultEndpoint, DefaultEndpointForm
+from cfme.common.provider_views import ProviderNodesView
+from cfme.exceptions import DestinationNotFound
+from utils.appliance.implementations.ui import CFMENavigateStep, navigator
 from . import InfraProvider
-from wrapanapi.virtualcenter import VMWareSystem
 
 
 class VirtualCenterEndpoint(DefaultEndpoint):
@@ -62,3 +67,15 @@ def view_value_mapping(self):
         return {'name': self.name,
                 'prov_type': 'VMware vCenter'
                 }
+
+
+@navigator.register(VMwareProvider, 'ProviderNodes')  # matching other infra class destinations
+class ProviderNodes(CFMENavigateStep):
+    VIEW = ProviderNodesView
+    prerequisite = NavigateToSibling('Details')
+
+    def step(self):
+        try:
+            self.prerequisite_view.contents.relationships.click_at('Hosts')
+        except NameError:
+            raise DestinationNotFound("Hosts aren't present on details page of this provider")


Test patch:
diff --git a/cfme/tests/infrastructure/test_host.py b/cfme/tests/infrastructure/test_host.py
--- a/cfme/tests/infrastructure/test_host.py
+++ b/cfme/tests/infrastructure/test_host.py
@@ -3,23 +3,17 @@
 import random
 
 import cfme.fixtures.pytest_selenium as sel
-from cfme.infrastructure.host import credential_form
+from cfme.base.credential import Credential
+from cfme.common.host_views import HostsEditView
+from cfme.common.provider_views import ProviderNodesView
 from cfme.infrastructure.provider import InfraProvider
-from cfme.web_ui import Quadicon, fill, toolbar as tb, flash
+from cfme.web_ui import Quadicon
 from utils import testgen
-from utils import version
-from utils import conf
+from utils.conf import credentials
 from utils.appliance.implementations.ui import navigate_to
 from cfme.infrastructure.provider.rhevm import RHEVMProvider
 
-pytestmark = [
-    pytest.mark.meta(blockers=[1296258]),
-    pytest.mark.tier(3),
-]
-
-
-def config_option():
-    return version.pick({version.LOWEST: 'Edit Selected Hosts', '5.4': 'Edit Selected items'})
+pytestmark = [pytest.mark.tier(3)]
 
 
 def pytest_generate_tests(metafunc):
@@ -42,56 +36,66 @@ def pytest_generate_tests(metafunc):
     testgen.parametrize(metafunc, argnames, new_argvalues, ids=new_idlist, scope="module")
 
 
-# Tests to automate BZ 1201092
-def test_multiple_host_good_creds(setup_provider, provider):
-    """  Tests multiple host credentialing  with good credentials """
+def navigate_and_select_quads(provider):
+    """navigate to the hosts edit page and select all the quads on the first page
 
-    details_view = navigate_to(provider, 'Details')
-    details_view.contents.relationships.click_at('Hosts')
+    Returns:
+        view: the provider nodes view, quadicons already selected"""
+    hosts_view = navigate_to(provider, 'ProviderNodes')
+    assert hosts_view.is_displayed
 
     quads = Quadicon.all("host", this_page=True)
     for quad in quads:
-            sel.check(quad.checkbox())
-    tb.select("Configuration", config_option())
+        sel.check(quad.checkbox())
+
+    hosts_view.toolbar.configuration.item_select('Edit Selected items')
+    edit_view = provider.create_view(HostsEditView)
+    assert edit_view.is_displayed
+
+    return edit_view
+
 
-    cfme_host = random.choice(provider.data["hosts"])
-    cred = cfme_host['credentials']
-    creds = conf.credentials[cred]
-    fill(credential_form, {'default_principal': creds['username'],
-                           'default_secret': creds['password'],
-                           'default_verify_secret': creds['password'],
-                           'validate_host': cfme_host["name"]})
+# Tests to automate BZ 1201092
+def test_multiple_host_good_creds(setup_provider, provider):
+    """  Tests multiple host credentialing  with good credentials """
+    host = random.choice(provider.data["hosts"])
+    creds = credentials[host['credentials']]
+    cred = Credential(principal=creds.username, secret=creds.password)
+
+    edit_view = navigate_and_select_quads(provider=provider)
 
-    sel.click(credential_form.validate_multi_host)
-    flash.assert_message_match('Credential validation was successful')
+    # Fill form with valid credentials for default endpoint and validate
+    edit_view.endpoints.default.fill_with(cred.view_value_mapping)
+    edit_view.validation_host.fill(host.name)
+    edit_view.endpoints.default.validate_button.click()
 
-    sel.click(credential_form.save_btn)
-    flash.assert_message_match('Credentials/Settings saved successfully')
+    edit_view.flash.assert_no_error()
+    edit_view.flash.assert_success_message('Credential validation was successful')
+
+    # Save changes
+    edit_view.save_button.click()
+    view = provider.create_view(ProviderNodesView)
+    view.flash.assert_no_error()
+    view.flash.assert_success_message('Credentials/Settings saved successfully')
 
 
 def test_multiple_host_bad_creds(setup_provider, provider):
     """    Tests multiple host credentialing with bad credentials """
+    host = random.choice(provider.data["hosts"])
+    bad_creds = credentials[host['credentials']]
+    bad_creds.update({'password': 'bad_password'})
+    cred = Credential(principal=bad_creds.username, secret=bad_creds.password)
 
-    details_view = navigate_to(provider, 'Details')
-    details_view.contents.relationships.click_at('Hosts')
-
-    quads = Quadicon.all("host", this_page=True)
-    for quad in quads:
-            sel.check(quad.checkbox())
-    tb.select("Configuration", config_option())
+    edit_view = navigate_and_select_quads(provider=provider)
 
-    cfme_host = random.choice(provider.data["hosts"])
-    creds = conf.credentials['bad_credentials']
-    fill(credential_form, {'default_principal': creds['username'],
-                           'default_secret': creds['password'],
-                           'default_verify_secret': creds['password'],
-                           'validate_host': cfme_host["name"]})
+    edit_view.endpoints.default.fill_with(cred.view_value_mapping)
+    edit_view.validation_host.fill(host.name)
+    edit_view.endpoints.default.validate_button.click()
 
-    sel.click(credential_form.validate_multi_host)
     if provider.one_of(RHEVMProvider):
         msg = 'Login failed due to a bad username or password.'
     else:
         msg = 'Cannot complete login due to an incorrect user name or password.'
-    flash.assert_message_match(msg)
+    edit_view.flash.assert_message(msg)
 
-    sel.click(credential_form.cancel_changes)
+    edit_view.cancel_button.click()