Source code for cfme.utils.appliance.implementations.ssui

from jsmin import jsmin
from navmazing import Navigate, NavigateStep
from selenium.common.exceptions import NoSuchElementException
from widgetastic.browser import Browser, DefaultPlugin

from cached_property import cached_property
from fixtures.pytest_store import store
from cfme.utils.browser import manager
from cfme.utils.log import logger, create_sublogger
from cfme.utils.wait import wait_for

from . import Implementation

[docs]class MiqSSUIBrowser(Browser): def __init__(self, selenium, endpoint, extra_objects=None): extra_objects = extra_objects or {} extra_objects.update({ 'appliance': endpoint.owner, 'endpoint': endpoint, 'store': store, }) super(MiqSSUIBrowser, self).__init__( selenium, plugin_class=MiqSSUIBrowserPlugin, logger=create_sublogger('MiqSSUIBrowser'), extra_objects=extra_objects) self.window_handle = selenium.current_window_handle @property def appliance(self): return self.extra_objects['appliance']
[docs] def create_view(self, *args, **kwargs): return self.appliance.ssui.create_view(*args, **kwargs)
@property def product_version(self): return self.appliance.version
[docs]class MiqSSUIBrowserPlugin(DefaultPlugin): ENSURE_PAGE_SAFE = jsmin(''' function checkProgressBar() { try { return $('#ngProgress').attr('style').indexOf('width: 0%') > -1; } catch(err) { // Not ready yet return false; } } function checkJquery() { if(typeof $ == 'undefined') { return true; } else { return !($.active > 0); } } return checkProgressBar() && checkJquery();''')
[docs] def ensure_page_safe(self, timeout='20s'): # THIS ONE SHOULD ALWAYS USE JAVASCRIPT ONLY, NO OTHER SELENIUM INTERACTION def _check(): result = self.browser.execute_script(self.ENSURE_PAGE_SAFE, silent=True) # TODO: Logging return bool(result) wait_for(_check, timeout=timeout, delay=2, silent_failure=True, very_quiet=True)
[docs] def after_keyboard_input(self, element, keyboard_input): self.browser.plugin.ensure_page_safe()
[docs]class SSUINavigateStep(NavigateStep): VIEW = None @cached_property def view(self): if self.VIEW is None: raise AttributeError('{} does not have VIEW specified'.format(type(self).__name__)) return self.create_view(self.VIEW, additional_context={'object': self.obj}) @property def appliance(self): return self.obj.appliance
[docs] def create_view(self, *args, **kwargs): return self.appliance.ssui.create_view(*args, **kwargs)
[docs] def am_i_here(self): try: return self.view.is_displayed except (AttributeError, NoSuchElementException): return False
[docs] def pre_navigate(self, *args, **kwargs): self.appliance.browser.open_browser(url_key=self.obj.appliance.server.address())
[docs] def do_nav(self, _tries=0, *args, **kwargs): """Describes how the navigation should take place.""" try: self.step(*args, **kwargs) except Exception as e: logger.error(e) raise self.go(_tries, *args, **kwargs)
[docs] def go(self, _tries=0): _tries += 1 self.pre_navigate(_tries) logger.debug("SSUI-NAVIGATE: Checking if already at {}".format(self._name)) here = False try: here = self.am_i_here() except Exception as e: logger.debug( "SSUI-NAVIGATE: Exception raised [{}] whilst checking if already at {}".format( e, self._name)) if here: logger.debug("SSUI-NAVIGATE: Already at {}".format(self._name)) else: logger.debug("SSUI-NAVIGATE: I'm not at {}".format(self._name)) self.prerequisite_view = self.prerequisite() logger.debug("SSUI-NAVIGATE: Heading to destination {}".format(self._name)) self.do_nav(_tries) self.resetter() self.post_navigate(_tries) if self.VIEW is not None: return self.view
navigator = Navigate() navigate_to = navigator.navigate
[docs]class ViaSSUI(Implementation): def __str__(self): return 'SSUI' @cached_property def widgetastic(self): """This gives us a widgetastic browser.""" # TODO: Make this a property that could watch for browser change? browser = self.open_browser(url_key=self.appliance.server.address()) wt = MiqSSUIBrowser(browser, self) manager.add_cleanup(self._reset_cache) return wt