Esempio n. 1
0
    '5.5':
    Table('//div[@id="list_grid"]/table'),
    '5.4':
    SplitTable(
        ('//*[@id="list_grid"]//table[contains(@class, "hdr")]/tbody', 1),
        ('//*[@id="list_grid"]//table[contains(@class, "obj")]/tbody', 1))
})

edit_tags_form = Form(fields=[(
    "select_tag",
    ui.Select("select#tag_cat")), ("select_value",
                                   ui.Select("select#tag_add"))])

nav.add_branch('clouds_stacks', {
    'clouds_stack':
    lambda ctx: sel.click(Quadicon(ctx['stack'].name, 'stack'))
})


class Stack(Pretty):
    pretty_attrs = ['name']

    def __init__(self, name=None):
        self.name = name

    def delete(self):
        sel.force_navigate('clouds_stack', context={'stack': self})
        cfg_btn("Remove this Stack from the VMDB", invokes_alert=True)
        sel.handle_alert()
        flash.assert_success_message(
            'The selected Orchestration Stack was deleted')
Esempio n. 2
0
def nav_to_cluster_through_provider(context):
    sel.force_navigate('infrastructure_provider', context=context)
    list_acc.select('Relationships', 'Clusters', by_title=False, partial=True)
    sel.click(Quadicon(context['cluster'].name, 'cluster'))
Esempio n. 3
0
 def step(self):
     list_acc.select('Relationships',
                     'Datastores',
                     by_title=False,
                     partial=True)
     sel.click(Quadicon(self.obj.name, self.obj.quad_name))
Esempio n. 4
0
def nav_to_datastore_through_provider(context):
    sel.force_navigate('infrastructure_provider', context=context)
    list_acc.select('Relationships', 'Show all managed Datastores')
    sel.click(Quadicon(context['datastore'].name, 'datastore'))
Esempio n. 5
0
from cfme.web_ui import Quadicon, Region, toolbar as tb
from functools import partial
from utils.pretty import Pretty
from utils.providers import get_crud
from utils.wait import wait_for

details_page = Region(infoblock_type='detail')

cfg_btn = partial(tb.select, 'Configuration')
pol_btn = partial(tb.select, 'Policy')

nav.add_branch(
    'infrastructure_resource_pools', {
        'infrastructure_resource_pool':
        lambda ctx: sel.click(
            Quadicon(ctx['resource_pool'].name, 'resource_pool'))
    })


class ResourcePool(Pretty):
    """ Model of an infrastructure Resource pool in cfme

    Args:
        name: Name of the Resource pool.
        provider_key: Name of the provider this resource pool is attached to.

    Note:
        If given a provider_key, it will navigate through ``Infrastructure/Providers`` instead
        of the direct path through ``Infrastructure/Resourcepool``.
    """
    pretty_attrs = ['name', 'provider_key']
Esempio n. 6
0
        ('infra_provider', {
            version.LOWEST: None,
            "5.4": Select("select#provider_id"),
            "5.5": AngularSelect("provider_id")}),
    ])

details_page = Region(infoblock_type='detail')

cfg_btn = partial(tb.select, 'Configuration')
pol_btn = partial(tb.select, 'Policy')
mon_btn = partial(tb.select, 'Monitoring')

nav.add_branch('clouds_providers',
               {'clouds_provider_new': lambda _: cfg_btn('Add a New Cloud Provider'),
                'clouds_provider_discover': lambda _: cfg_btn('Discover Cloud Providers'),
                'clouds_provider': [lambda ctx: sel.click(Quadicon(ctx['provider'].name,
                                                                  'cloud_prov')),
                                   {'clouds_provider_edit':
                                    lambda _: cfg_btn('Edit this Cloud Provider'),
                                    'clouds_provider_policy_assignment':
                                    lambda _: pol_btn('Manage Policies'),
                                    'cloud_provider_timelines':
                                    lambda _: mon_btn('Timelines')}]})


class Provider(Pretty, CloudInfraProvider):
    """
    Abstract model of a cloud provider in cfme. See EC2Provider or OpenStackProvider.

    Args:
        name: Name of the provider.
        details: a details record (see EC2Details, OpenStackDetails inner class).
Esempio n. 7
0
nav.add_branch(
    'infrastructure_config_management', {
        'infrastructure_config_managers': [
            lambda _: (accordion.tree(
                'Providers',
                version.pick({
                    version.LOWEST: 'All Red Hat Satellite Providers',
                    version.UPSTREAM: 'All Foreman Providers'
                })), toolbar.set_vms_grid_view()),
            {
                'infrastructure_config_manager_new':
                lambda _: cfg_btn('Add a new Provider'),
                'infrastructure_config_manager': [
                    lambda ctx: sel.check(
                        Quadicon(
                            '{} Configuration Manager'.
                            format(ctx['manager'].name), None).checkbox), {
                                'infrastructure_config_manager_edit':
                                lambda _: cfg_btn('Edit Selected item'),
                                'infrastructure_config_manager_refresh':
                                lambda _: cfg_btn(
                                    'Refresh Relationships and Power states',
                                    invokes_alert=True),
                                'infrastructure_config_manager_remove':
                                lambda _: cfg_btn(
                                    'Remove selected items from the VMDB',
                                    invokes_alert=True)
                            }
                ],
                'infrastructure_config_manager_detail': [
                    lambda ctx: sel.click(
Esempio n. 8
0
def test_run_datastore_analysis(request, setup_provider, provider, datastore,
                                soft_assert):
    """Tests smarthost analysis

    Metadata:
        test_flag: datastore_analysis
    """

    # Check if there is a host with valid credentials
    host_names = datastore.get_hosts()
    assert len(host_names) != 0, "No hosts attached to this datastore found"
    for host_name in host_names:
        host_qi = Quadicon(host_name, 'host')
        if 'checkmark' in host_qi.creds:
            break
    else:
        # If not, get credentials for one of the present hosts
        found_host = False
        for host_name in host_names:
            host_data = get_host_data_by_name(provider.key, host_name)
            if host_data is None:
                continue

            found_host = True
            test_host = host.Host(name=host_name)

            # Add them to the host
            wait_for(lambda: test_host.exists,
                     delay=10,
                     num_sec=120,
                     fail_func=sel.refresh)
            if not test_host.has_valid_credentials:
                test_host.update(
                    updates={
                        'credentials':
                        host.get_credentials_from_config(
                            host_data['credentials'])
                    })
                wait_for(lambda: test_host.has_valid_credentials,
                         delay=10,
                         num_sec=120,
                         fail_func=sel.refresh)

                # And remove them again when the test is finished
                def test_host_remove_creds():
                    test_host.update(
                        updates={
                            'credentials':
                            host.Host.Credential(
                                principal="", secret="", verify_secret="")
                        })

                request.addfinalizer(test_host_remove_creds)
            break

        assert found_host,\
            "No credentials found for any of the hosts attached to datastore {}"\
            .format(datastore.name)

    # TODO add support for events
    # register_event(
    #     None,
    #     "datastore",
    #     datastore_name,
    #     ["datastore_analysis_request_req", "datastore_analysis_complete_req"]
    # )

    # Initiate analysis
    datastore.run_smartstate_analysis()
    wait_for(lambda: is_datastore_analysis_finished(datastore.name),
             delay=15,
             timeout="10m",
             fail_func=lambda: toolbar.select('Reload'))

    c_datastore = datastore.get_detail('Properties', 'Datastore Type')
    # Check results of the analysis and the datastore type
    soft_assert(
        c_datastore == datastore.type.upper(),
        'Datastore type does not match the type defined in yaml:' +
        'expected "{}" but was "{}"'.format(datastore.type.upper(),
                                            c_datastore))
    for row_name in CONTENT_ROWS_TO_CHECK:
        value = InfoBlock('Content', row_name).text
        soft_assert(value != '0',
                    'Expected value for {} to be non-empty'.format(row_name))
Esempio n. 9
0
def test_run_datastore_analysis(request, setup_provider, provider, datastore_type, datastore_name):
    """Tests smarthost analysis

    Metadata:
        test_flag: datastore_analysis
    """
    test_datastore = datastore.Datastore(datastore_name, provider.key)

    # Check if there is a host with valid credentials
    host_names = test_datastore.get_hosts()
    assert len(host_names) != 0, "No hosts attached to this datastore found"
    for host_name in host_names:
        host_qi = Quadicon(host_name, 'host')
        if host_qi.creds == 'checkmark':
            break
    else:
        # If not, get credentials for one of the present hosts
        found_host = False
        for host_name in host_names:
            host_data = get_host_data_by_name(provider.key, host_name)
            if host_data is None:
                continue

            found_host = True
            test_host = host.Host(name=host_name)

            # Add them to the host
            wait_for(lambda: test_host.exists, delay=10, num_sec=120, fail_func=sel.refresh)
            if not test_host.has_valid_credentials:
                test_host.update(
                    updates={
                        'credentials': host.get_credentials_from_config(host_data['credentials'])}
                )
                wait_for(
                    lambda: test_host.has_valid_credentials,
                    delay=10,
                    num_sec=120,
                    fail_func=sel.refresh
                )

                # And remove them again when the test is finished
                def test_host_remove_creds():
                    test_host.update(
                        updates={
                            'credentials': host.Host.Credential(
                                principal="",
                                secret="",
                                verify_secret=""
                            )
                        }
                    )
                request.addfinalizer(test_host_remove_creds)
            break

        assert found_host,\
            "No credentials found for any of the hosts attached to datastore {}"\
            .format(datastore_name)

    # TODO add support for events
    # register_event(
    #     None,
    #     "datastore",
    #     datastore_name,
    #     ["datastore_analysis_request_req", "datastore_analysis_complete_req"]
    # )

    # Initiate analysis
    sel.force_navigate('infrastructure_datastore', context={
        'datastore': test_datastore,
        'provider': test_datastore.provider
    })
    tb.select('Configuration', 'Perform SmartState Analysis', invokes_alert=True)
    sel.handle_alert()
    flash.assert_message_contain('"{}": scan successfully initiated'.format(datastore_name))

    # Wait for the task to finish
    def is_datastore_analysis_finished():
        """ Check if analysis is finished - if not, reload page
        """
        if not sel.is_displayed(tasks.tasks_table) or not tabs.is_tab_selected('All Other Tasks'):
            sel.force_navigate('tasks_all_other')
        host_analysis_finished = tasks.tasks_table.find_row_by_cells({
            'task_name': "SmartState Analysis for [{}]".format(datastore_name),
            'state': 'Finished'
        })
        return host_analysis_finished is not None

    wait_for(
        is_datastore_analysis_finished,
        delay=10,
        num_sec=300,
        fail_func=lambda: tb.select('Reload')
    )

    # Delete the task
    tasks.tasks_table.select_row_by_cells({
        'task_name': "SmartState Analysis for [{}]".format(datastore_name),
        'state': 'Finished'
    })
    tb.select('Delete Tasks', 'Delete', invokes_alert=True)
    sel.handle_alert()

    # Check results of the analysis and the datastore type
    assert test_datastore.get_detail('Properties', 'Datastore Type') == datastore_type.upper(),\
        'Datastore type does not match the type defined in yaml'
    for row_name in CONTENT_ROWS_TO_CHECK:
        assert test_datastore.get_detail('Content', row_name) != '0',\
            '{} in Content infoblock should not be 0'.format(row_name)
Esempio n. 10
0
 def step(self):
     sel.check(Quadicon(self.obj.name, self.obj.quad_name).checkbox())
     pol_btn('Manage Policies')
Esempio n. 11
0
 def step(self):
     sel.check(Quadicon(self.obj.name, self.obj.quad_name).checkbox())
     cfg = self.prerequisite_view.toolbar.configuration
     cfg.item_select('Edit Selected Infrastructure Providers')
Esempio n. 12
0
 def _wait_f():
     navigate_to(self, 'All')
     q = Quadicon(self.name, self.quad_name)
     creds = q.creds
     return "checkmark" in creds
Esempio n. 13
0
    version.LOWEST: "//div[@id='treebox']/div/table",
    "5.3": "//div[@id='protect_treebox']/ul"
})

cfg_btn = partial(tb.select, 'Configuration')
pol_btn = partial(tb.select, 'Policy')
mon_btn = partial(tb.select, 'Monitoring')

nav.add_branch(
    'infrastructure_providers', {
        'infrastructure_provider_new':
        lambda _: cfg_btn('Add a New Infrastructure Provider'),
        'infrastructure_provider_discover':
        lambda _: cfg_btn('Discover Infrastructure Providers'),
        'infrastructure_provider': [
            lambda ctx: sel.click(Quadicon(ctx[
                'provider'].name, 'infra_prov')), {
                    'infrastructure_provider_edit':
                    lambda _: cfg_btn('Edit this Infrastructure Provider'),
                    'infrastructure_provider_policy_assignment':
                    lambda _: pol_btn('Manage Policies'),
                    'infrastructure_provider_timelines':
                    lambda _: mon_btn('Timelines')
                }
        ]
    })


class Provider(Pretty, CloudInfraProvider):
    """
    Abstract model of an infrastructure provider in cfme. See VMwareProvider or RHEVMProvider.
Esempio n. 14
0
def wait_for_provider_delete(provider):
    sel.force_navigate('clouds_providers')
    quad = Quadicon(provider.name, 'cloud_prov')
    logger.info('Waiting for a provider to delete...')
    wait_for(lambda prov: not sel.is_displayed(prov), func_args=[quad], fail_condition=False,
             message="Wait provider to disappear", num_sec=1000, fail_func=sel.refresh)
Esempio n. 15
0
def wait_for_host_to_appear(host):
    sel.force_navigate('infrastructure_hosts')
    quad = Quadicon(host.name, 'host')
    logger.info('Waiting for a host to appear...')
    wait_for(sel.is_displayed, func_args=[quad], fail_condition=False,
             message="Wait host to appear", num_sec=1000, fail_func=sel.refresh)
 def exists(self):
     """Returns whether the manager exists in the UI or not"""
     navigate_to(self, 'All')
     if (Quadicon.any_present() and Quadicon(self.quad_name, None).exists):
         return True
     return False
Esempio n. 17
0
    }))

host_add_btn = FormButton('Add this Host')

cfg_btn = partial(tb.select, 'Configuration')
pol_btn = partial(tb.select, 'Policy')
pow_btn = partial(tb.select, 'Power')

nav.add_branch(
    'infrastructure_hosts', {
        'infrastructure_host_new':
        lambda _: cfg_btn('Add a New Host'),
        'infrastructure_host_discover':
        lambda _: cfg_btn('Discover Hosts'),
        'infrastructure_host': [
            lambda ctx: sel.click(Quadicon(ctx['host'].name, 'host')), {
                'infrastructure_host_edit':
                lambda _: cfg_btn('Edit this Host'),
                'infrastructure_host_policy_assignment':
                lambda _: pol_btn('Manage Policies')
            }
        ]
    })


class Host(Updateable):
    """
    Model of an infrastructure host in cfme.

    Args:
        name: Name of the host.
 def step(self):
     sel.check(Quadicon(self.obj.quad_name, None).checkbox())
     cfg_btn('Edit Selected item')
Esempio n. 19
0
                         toolbar as tb, InfoBlock)
from cfme.web_ui.menu import nav
from utils.browser import ensure_browser_open
from utils.db import cfmedb
from utils.pretty import Pretty
from utils.varmeth import variable

from . import cfg_btn, mon_btn, pol_btn, details_page

nav.add_branch(
    'containers_providers', {
        'containers_provider_new':
        lambda _: cfg_btn('Add a New Containers Provider'),
        'containers_provider': [
            lambda ctx: sel.check(
                Quadicon(ctx['provider'].name, None).checkbox), {
                    'containers_provider_edit':
                    lambda _: cfg_btn('Edit Selected Containers Provider'),
                    'containers_provider_edit_tags':
                    lambda _: pol_btn('Edit Tags')
                }
        ],
        'containers_provider_detail': [
            lambda ctx: sel.click(Quadicon(ctx['provider'].name, None)), {
                'containers_provider_edit_detail':
                lambda _: cfg_btn('Edit this Containers Provider'),
                'containers_provider_timelines_detail':
                lambda _: mon_btn('Timelines'),
                'containers_provider_edit_tags_detail':
                lambda _: pol_btn('Edit Tags'),
                'containers_provider_topology_detail':
 def step(self):
     sel.check(Quadicon(self.obj.name, None))
     cfg_btn('Provision Configured Systems')
Esempio n. 21
0
details_page = Region(infoblock_type='detail')

cfg_btn = partial(tb.select, 'Configuration')
pol_btn = partial(tb.select, 'Policy')


def nav_to_datastore_through_provider(context):
    sel.force_navigate('infrastructure_provider', context=context)
    list_acc.select('Relationships', 'Show all managed Datastores')
    sel.click(Quadicon(context['datastore'].name, 'datastore'))


nav.add_branch(
    'infrastructure_datastores', {
        'infrastructure_datastore':
        lambda ctx: sel.click(Quadicon(ctx['datastore'].name, 'datastore'))
        if 'provider' not in ctx else nav_to_datastore_through_provider(ctx)
    })


class Datastore(Pretty):
    """ Model of an infrastructure datastore in cfme

    Args:
        name: Name of the datastore.
        provider_key: Name of the provider this datastore is attached to.

    Note:
        If given a provider_key, it will navigate through ``Infrastructure/Providers`` instead
        of the direct path through ``Infrastructure/Datastores``.
    """
 def step(self):
     sel.check(Quadicon(self.obj.name, None))
     cfg_btn('Edit Tags')
Esempio n. 23
0
 def _wait_f():
     sel.force_navigate("{}_providers".format(self.page_name))
     q = Quadicon(self.name, self.quad_name)
     creds = q.creds
     return creds == "checkmark"
Esempio n. 24
0
def navigate_quadicons(q_names,
                       q_type,
                       page_name,
                       nav_limit,
                       ui_worker_pid,
                       prod_tail,
                       soft_assert,
                       acc_topbars=[]):
    pages = []
    count = 0
    if nav_limit == 0:
        count = -1
    assert len(q_names) > 0
    while (count < nav_limit):
        for q in q_names:
            for page in paginator.pages():
                quadicon = Quadicon(str(q), q_type)
                if sel.is_displayed(quadicon):

                    pages.extend(
                        analyze_page_stat(
                            perf_click(ui_worker_pid, prod_tail, True,
                                       sel.click, quadicon), soft_assert))

                    for topbar in acc_topbars:
                        try:
                            if not list_acc.is_active(topbar):
                                list_acc.click(topbar)
                            links = list_acc.get_active_links(topbar)
                            for link in range(len(links)):
                                # Every click makes the previous list of links invalid
                                links = list_acc.get_active_links(topbar)
                                if link <= len(links):
                                    # Do not navigate to any link containing:
                                    dnn = [
                                        'parent', 'Capacity & Utilization',
                                        'Timelines',
                                        'Show tree of all VMs by Resource Pool in this Cluster',
                                        'Show host drift history', 'Show VMs'
                                    ]
                                    if any_in(dnn, links[link].title):
                                        logger.debug('DNN Skipping: %s',
                                                     links[link].title)
                                    else:
                                        pages.extend(
                                            analyze_page_stat(
                                                perf_click(
                                                    ui_worker_pid, prod_tail,
                                                    True, links[link].click),
                                                soft_assert))

                        except NoSuchElementException:
                            logger.warning(
                                'NoSuchElementException - page_name:%s, Quadicon:%s,'
                                ' topbar:%s', page_name, q, topbar)
                            soft_assert(
                                False,
                                'NoSuchElementException - page_name:{}, Quadicon:{},'
                                ' topbar:{}'.format(page_name, q, topbar))
                            break
                    count += 1
                    break

            pages.extend(
                analyze_page_stat(
                    perf_click(ui_worker_pid, prod_tail, True,
                               sel.force_navigate, page_name), soft_assert))
            # If nav_limit == 0 , every item is navigated to
            if not nav_limit == 0 and count == nav_limit:
                break

    return pages
Esempio n. 25
0
details_page = Region(infoblock_type='detail')

cfg_btn = partial(tb.select, 'Configuration')
pol_btn = partial(tb.select, 'Policy')


def nav_to_cluster_through_provider(context):
    sel.force_navigate('infrastructure_provider', context=context)
    list_acc.select('Relationships', 'Clusters', by_title=False, partial=True)
    sel.click(Quadicon(context['cluster'].name, 'cluster'))


nav.add_branch(
    'infrastructure_clusters', {
        'infrastructure_cluster':
        lambda ctx: sel.click(Quadicon(ctx['cluster'].name, 'cluster'))
        if 'provider' not in ctx else nav_to_cluster_through_provider(ctx)
    })


class Cluster(Pretty):
    """ Model of an infrastructure cluster in cfme

    Args:
        name: Name of the cluster.
        provider_key: Name of the provider this cluster is attached to.

    Note:
        If given a provider_key, it will navigate through ``Infrastructure/Providers`` instead
        of the direct path through ``Infrastructure/Clusters``.
    """
Esempio n. 26
0
    version.LOWEST: FormButton('Add this Host'),
    "5.5": FormButton("Add")
}
default_host_filter_btn = FormButton('Set the current filter as my default')
cfg_btn = partial(tb.select, 'Configuration')
pol_btn = partial(tb.select, 'Policy')
pow_btn = partial(tb.select, 'Power')
lif_btn = partial(tb.select, 'Lifecycle')

nav.add_branch('infrastructure_hosts',
               {'infrastructure_host_new': lambda _: cfg_btn(
                   version.pick({version.LOWEST: 'Add a New Host',
                                 '5.4': 'Add a New item'})),
                'infrastructure_host_discover': lambda _: cfg_btn(
                    'Discover Hosts'),
                'infrastructure_host': [lambda ctx: sel.click(Quadicon(ctx['host'].name,
                                                                      'host')),
                                   {'infrastructure_host_edit':
                                    lambda _: cfg_btn(
                                        version.pick({version.LOWEST: 'Edit this Host',
                                                      '5.4': 'Edit this item'})),
                                    'infrastructure_host_policy_assignment':
                                    lambda _: pol_btn('Manage Policies'),
                                    'infrastructure_provision_host':
                                    lambda _: lif_btn(
                                        version.pick({version.LOWEST: 'Provision this Host',
                                                      '5.4': 'Provision this item'}))}]})


class Host(Updateable, Pretty):
    """
    Model of an infrastructure host in cfme.
Esempio n. 27
0
 def step(self):
     sel.click(Quadicon(self.obj.name, self.obj.quad_name))
Esempio n. 28
0
def wait_for_host_delete(host):
    sel.force_navigate('infrastructure_hosts')
    quad = Quadicon(host.name, 'host')
    logger.info('Waiting for a host to delete...')
    wait_for(lambda: not sel.is_displayed(quad), fail_condition=False,
             message="Wait host to disappear", num_sec=500, fail_func=sel.refresh)
Esempio n. 29
0
def _setup_providers(cloud_or_infra, validate, check_existing):
    """Helper to set up all cloud or infra providers, and then validate them

    Args:
        cloud_or_infra: Like the name says: 'cloud' or 'infra' (a string)
        validate: see description in :py:func:`setup_provider`
        check_existing: see description in :py:func:`setup_provider`

    Returns:
        A list of provider objects that have been created.

    """
    # Pivot behavior on cloud_or_infra
    options_map = {
        'cloud': {
            'navigate': 'clouds_providers',
            'quad': 'cloud_prov',
            'list': list_cloud_providers
        },
        'infra': {
            'navigate': 'infrastructure_providers',
            'quad': 'infra_prov',
            'list': list_infra_providers
        }
    }
    # Check for existing providers all at once, to prevent reloading
    # the providers page for every provider in cfme_data
    if not options_map[cloud_or_infra]['list']():
        return []
    if check_existing:
        sel.force_navigate(options_map[cloud_or_infra]['navigate'])
        add_providers = []
        for provider_key in options_map[cloud_or_infra]['list']():
            provider_name = conf.cfme_data.get('management_systems',
                                               {})[provider_key]['name']
            quad = Quadicon(provider_name, options_map[cloud_or_infra]['quad'])
            for page in paginator.pages():
                if sel.is_displayed(quad):
                    logger.debug('Provider "%s" exists, skipping' %
                                 provider_key)
                    break
            else:
                add_providers.append(provider_key)
    else:
        # Add all cloud or infra providers unconditionally
        add_providers = options_map[cloud_or_infra]['list']()

    if add_providers:
        logger.info('Providers to be added: %s' % ', '.join(add_providers))

    # Save the provider objects for validation and return
    added_providers = []

    for provider_name in add_providers:
        # Don't validate in this step; add all providers, then go back and validate in order
        provider = setup_provider(provider_name,
                                  validate=False,
                                  check_existing=False)
        added_providers.append(provider)

    if validate:
        map(methodcaller('validate'), added_providers)

    return added_providers
Esempio n. 30
0
 def check_vm_add(self, add_vm_name):
     view = navigate_to(self, 'Details')
     # TODO - replace Quadicon later
     quadicon = Quadicon(add_vm_name, "vm")
     sel.click(quadicon)
     view.flash.assert_no_error()