def test_cannot_delete_more_than_once(single_provider): """When Delete button appars, it does not want to go away""" filter_name = fauxfactory.gen_alphanumeric() assert search.save_filter("fill_count(Infrastructure Provider.VMs, >, 0)", filter_name) assert search.load_filter(filter_name) # circumvent the thing happening in previous test # Delete once if not search.delete_filter(): pytest.fail("Could not delete the filter even first time!") assert_no_cfme_exception() # Try it second time if search.delete_filter(): # If the button is there, it says True # This should not happen msg = "Delete twice accepted!" if is_cfme_exception(): msg += " CFME Exception text: `{}`".format(cfme_exception_text()) pytest.fail(msg)
def test_cannot_delete_more_than_once(): """When Delete button appars, it does not want to go away""" filter_name = fauxfactory.gen_alphanumeric() assert search.save_filter("fill_count(Infrastructure Provider.VMs, >, 0)", filter_name) assert search.load_filter(filter_name) # circumvent the thing happening in previous test # Delete once if not search.delete_filter(): pytest.fail("Could not delete the filter even first time!") assert_no_cfme_exception() # Try it second time if search.delete_filter(): # If the button is there, it says True # This should not happen msg = "Delete twice accepted!" if is_cfme_exception(): msg += " CFME Exception text: `{}`".format(cfme_exception_text()) pytest.fail(msg)
def test_cannot_delete_more_than_once(request, nuke_browser_after_test): """When Delete button appars, it does not want to go away""" pytest.sel.force_navigate("infrastructure_hosts") filter_name = fauxfactory.gen_alphanumeric() search.save_filter(get_expression(False).format(0), filter_name) search.load_filter(filter_name) # circumvent the thing happening in previous test # Delete once if not search.delete_filter(): pytest.fail("Could not delete the filter even first time!") assert_no_cfme_exception() # Try it second time if search.delete_filter(): # If the button is there, it says True # This should not happen msg = "Delete twice accepted!" if is_cfme_exception(): msg += " CFME Exception text: `{}`".format(cfme_exception_text()) pytest.fail(msg)
def test_cannot_delete_more_than_once(request, nuke_browser_after_test): """When Delete button appars, it does not want to go away""" navigate_to(Host, 'All') filter_name = fauxfactory.gen_alphanumeric() search.save_filter(get_expression(False).format(0), filter_name) search.load_filter(filter_name) # circumvent the thing happening in previous test # Delete once if not search.delete_filter(): pytest.fail("Could not delete the filter even first time!") assert_no_cfme_exception() # Try it second time if search.delete_filter(): # If the button is there, it says True # This should not happen msg = "Delete twice accepted!" if is_cfme_exception(): msg += " CFME Exception text: `{}`".format(cfme_exception_text()) pytest.fail(msg)
def test_cannot_delete_more_than_once(request): """When Delete button appars, it does not want to go away""" sel.force_navigate("infra_vms") filter_name = fauxfactory.gen_alphanumeric() search.save_filter("fill_count(Virtual Machine.Files, >, 0)", filter_name) search.load_filter(filter_name) # circumvent the thing happening in previous test # Delete once if not search.delete_filter(): pytest.fail("Could not delete the filter even first time!") assert_no_cfme_exception() # Try it second time if search.delete_filter(): # If the button is there, it says True # This should not happen msg = "Delete twice accepted!" if is_cfme_exception(): msg += " CFME Exception text: `{}`".format(cfme_exception_text()) pytest.fail(msg)
def test_cannot_delete_more_than_once(vm_advanced_search, nuke_browser_after_test): """When Delete button appars, it does not want to go away""" filter_name = fauxfactory.gen_alphanumeric() vm_advanced_search.entities.search.save_filter( "fill_count(Virtual Machine.Files, >, 0)", filter_name) # circumvent the thing happening in previous test vm_advanced_search.entities.search.load_filter(filter_name) # Delete once if not vm_advanced_search.entities.search.delete_filter(): pytest.fail("Could not delete the filter even first time!") vm_advanced_search.flash.assert_no_error() # Try it second time if vm_advanced_search.entities.search.delete_filter(): # If the button is there, it says True # This should not happen reduntant msg = "Delete twice accepted!" if is_cfme_exception(): msg += " CFME Exception text: `{}`".format(cfme_exception_text()) pytest.fail(msg)
def test_cannot_delete_more_than_once(request): """When Delete button appars, it does not want to go away""" sel.force_navigate("infrastructure_hosts") filter_name = generate_random_string() search.save_filter("fill_count(Host.VMs, >, 0)", filter_name) search.load_filter( filter_name) # circumvent the thing happening in previous test # Delete once if not search.delete_filter(): pytest.fail("Could not delete the filter even first time!") assert_no_cfme_exception() # Try it second time if search.delete_filter(): # If the button is there, it says True # This should not happen msg = "Delete twice accepted!" if is_cfme_exception(): msg += " CFME Exception text: `{}`".format(cfme_exception_text()) pytest.fail(msg)
def test_cannot_delete_more_than_once(host_collection, hosts_advanced_search, nuke_browser_after_test): """When Delete button appars, it does not want to go away""" filter_name = fauxfactory.gen_alphanumeric() hosts_advanced_search.entities.search.save_filter(get_expression(False).format(0), filter_name) # circumvent the thing happening in previous test hosts_advanced_search.entities.search.load_filter(filter_name) # Delete once if not hosts_advanced_search.entities.search.delete_filter(): pytest.fail("Could not delete the filter even first time!") hosts_advanced_search.flash.assert_no_error() # Try it second time # If the button is there, it says True if hosts_advanced_search.entities.search.delete_filter(): # This should not happen msg = "Delete twice accepted!" if is_cfme_exception(): msg += " CFME Exception text: `{}`".format(cfme_exception_text()) pytest.fail(msg)
def force_navigate(page_name, _tries=0, *args, **kwargs): """force_navigate(page_name) Given a page name, attempt to navigate to that page no matter what breaks. Args: page_name: Name a page from the current :py:data:`ui_navigate.nav_tree` tree to navigate to. """ if _tries > 2: # Need at least three tries: # 1: login_admin handles an alert or CannotContinueWithNavigation appears. # 2: Everything should work. If not, NavigationError. raise exceptions.NavigationError(page_name) _tries += 1 logger.debug('force_navigate to %s, try %d' % (page_name, _tries)) # circular import prevention: cfme.login uses functions in this module from cfme import login # Import the top-level nav menus for convenience from cfme.web_ui import menu # browser fixture should do this, but it's needed for subsequent calls ensure_browser_open() # Clear any running "spinnies" try: execute_script('miqSparkleOff();') except: # miqSparkleOff undefined, so it's definitely off. pass # Set this to True in the handlers below to trigger a browser restart recycle = False # remember the current user, if any current_user = login.current_user() try: # What we'd like to happen... if not current_user: # default to admin user login.login_admin() else: # we recycled and want to log back in login.login(current_user.username, current_user.password) logger.info('Navigating to %s' % page_name) menu.nav.go_to(page_name, *args, **kwargs) except (KeyboardInterrupt, ValueError): # KeyboardInterrupt: Don't block this while navigating # ValueError: ui_navigate.go_to can't handle this page, give up raise except UnexpectedAlertPresentException: if _tries == 1: # There was an alert, accept it and try again handle_alert(wait=0) force_navigate(page_name, _tries, *args, **kwargs) else: # There was still an alert when we tried again, shoot the browser in the head logger.debug('Unxpected alert, recycling browser') recycle = True except (ErrorInResponseException, InvalidSwitchToTargetException): # Unable to switch to the browser at all, need to recycle logger.info('Invalid browser state, recycling browser') recycle = True except exceptions.CannotContinueWithNavigation as e: # The some of the navigation steps cannot succeed logger.info('Cannot continue with navigation due to: %s; Recycling browser' % str(e)) recycle = True except (NoSuchElementException, InvalidElementStateException, WebDriverException): from cfme.web_ui import cfme_exception as cfme_exc # To prevent circular imports # If the page is blocked, then recycle... if is_displayed("//div[@id='blocker_div']"): logger.warning("Page was blocked with blocker div, recycling.") recycle = True elif cfme_exc.is_cfme_exception(): logger.exception("CFME Exception before force_navigate started!: `{}`".format( cfme_exc.cfme_exception_text() )) recycle = True elif is_displayed("//body/div[@class='dialog' and ./h1 and ./p]"): # Rails exception detection logger.exception("Rails exception before force_navigate started!: {}:{} at {}".format( text("//body/div[@class='dialog']/h1").encode("utf-8"), text("//body/div[@class='dialog']/p").encode("utf-8"), current_url() )) recycle = True elif elements("//ul[@id='maintab']/li[@class='inactive']") and not\ elements("//ul[@id='maintab']/li[@class='active']/ul/li"): # If upstream and is the bottom part of menu is not displayed logger.exception("Detected glitch from BZ#1112574. HEADSHOT!") recycle = True else: logger.error("Could not determine the reason for failing the navigation. Reraising.") raise if recycle: browser().quit() # login.current_user() will be retained for next login logger.debug('browser killed on try %d' % _tries) # If given a "start" nav destination, it won't be valid after quitting the browser kwargs.pop("start", None) force_navigate(page_name, _tries, *args, **kwargs)
def force_navigate(page_name, _tries=0, *args, **kwargs): """force_navigate(page_name) Given a page name, attempt to navigate to that page no matter what breaks. Args: page_name: Name a page from the current :py:data:`ui_navigate.nav_tree` tree to navigate to. """ if _tries > 2: # Need at least three tries: # 1: login_admin handles an alert or CannotContinueWithNavigation appears. # 2: Everything should work. If not, NavigationError. raise exceptions.NavigationError(page_name) _tries += 1 logger.debug('force_navigate to %s, try %d' % (page_name, _tries)) # circular import prevention: cfme.login uses functions in this module from cfme import login # Import the top-level nav menus for convenience from cfme.web_ui import menu # browser fixture should do this, but it's needed for subsequent calls ensure_browser_open() # Clear any running "spinnies" try: execute_script('miqSparkleOff();') except: # miqSparkleOff undefined, so it's definitely off. pass # Set this to True in the handlers below to trigger a browser restart recycle = False # remember the current user, if any current_user = login.current_user() try: # What we'd like to happen... if not current_user: # default to admin user login.login_admin() else: # we recycled and want to log back in login.login(current_user.username, current_user.password) logger.info('Navigating to %s' % page_name) menu.nav.go_to(page_name, *args, **kwargs) except (KeyboardInterrupt, ValueError): # KeyboardInterrupt: Don't block this while navigating # ValueError: ui_navigate.go_to can't handle this page, give up raise except UnexpectedAlertPresentException: if _tries == 1: # There was an alert, accept it and try again handle_alert(wait=0) force_navigate(page_name, _tries, *args, **kwargs) else: # There was still an alert when we tried again, shoot the browser in the head logger.debug('Unxpected alert, recycling browser') recycle = True except (ErrorInResponseException, InvalidSwitchToTargetException): # Unable to switch to the browser at all, need to recycle logger.info('Invalid browser state, recycling browser') recycle = True except exceptions.CannotContinueWithNavigation as e: # The some of the navigation steps cannot succeed logger.info( 'Cannot continue with navigation due to: %s; Recycling browser' % str(e)) recycle = True except (NoSuchElementException, InvalidElementStateException, WebDriverException): from cfme.web_ui import cfme_exception as cfme_exc # To prevent circular imports # If the page is blocked, then recycle... if is_displayed("//div[@id='blocker_div']"): logger.warning("Page was blocked with blocker div, recycling.") recycle = True elif cfme_exc.is_cfme_exception(): logger.exception( "CFME Exception before force_navigate started!: `{}`".format( cfme_exc.cfme_exception_text())) recycle = True elif is_displayed("//body/div[@class='dialog' and ./h1 and ./p]"): # Rails exception detection logger.exception( "Rails exception before force_navigate started!: {}:{} at {}". format( text("//body/div[@class='dialog']/h1").encode("utf-8"), text("//body/div[@class='dialog']/p").encode("utf-8"), current_url())) recycle = True elif elements("//ul[@id='maintab']/li[@class='inactive']") and not\ elements("//ul[@id='maintab']/li[@class='active']/ul/li"): # If upstream and is the bottom part of menu is not displayed logger.exception("Detected glitch from BZ#1112574. HEADSHOT!") recycle = True else: logger.error( "Could not determine the reason for failing the navigation. Reraising." ) raise if recycle: browser().quit( ) # login.current_user() will be retained for next login logger.debug('browser killed on try %d' % _tries) # If given a "start" nav destination, it won't be valid after quitting the browser kwargs.pop("start", None) force_navigate(page_name, _tries, *args, **kwargs)
def check_for_badness(self, fn, _tries, nav_args, *args, **kwargs): if getattr(fn, '_can_skip_badness_test', False): # self.log_message('Op is a Nop! ({})'.format(fn.__name__)) return if self.VIEW: self.view.flush_widget_cache() go_kwargs = kwargs.copy() go_kwargs.update(nav_args) self.appliance.browser.open_browser(url_key=self.obj.appliance.server.address()) # check for MiqQE javascript patch on first try and patch the appliance if necessary if self.appliance.is_miqqe_patch_candidate and not self.appliance.miqqe_patch_applied: self.appliance.patch_with_miqqe() self.appliance.browser.quit_browser() _tries -= 1 self.go(_tries, *args, **go_kwargs) br = self.appliance.browser try: br.widgetastic.execute_script('miqSparkleOff();', silent=True) except: # noqa # miqSparkleOff undefined, so it's definitely off. # Or maybe it is alerts? Let's only do this when we get an exception. self.appliance.browser.widgetastic.dismiss_any_alerts() # If we went so far, let's put diapers on one more miqSparkleOff just to be sure # It can be spinning in the back try: br.widgetastic.execute_script('miqSparkleOff();', silent=True) except: # noqa pass # Check if the page is blocked with blocker_div. If yes, let's headshot the browser right # here if ( br.widgetastic.is_displayed("//div[@id='blocker_div' or @id='notification']") or br.widgetastic.is_displayed(".modal-backdrop.fade.in")): logger.warning("Page was blocked with blocker div on start of navigation, recycling.") self.appliance.browser.quit_browser() self.go(_tries, *args, **go_kwargs) # Check if modal window is displayed if (br.widgetastic.is_displayed( "//div[contains(@class, 'modal-dialog') and contains(@class, 'modal-lg')]")): logger.warning("Modal window was open; closing the window") br.widgetastic.click( "//button[contains(@class, 'close') and contains(@data-dismiss, 'modal')]") # Check if jQuery present try: br.widgetastic.execute_script("jQuery", silent=True) except Exception as e: if "jQuery" not in str(e): logger.error("Checked for jQuery but got something different.") logger.exception(e) # Restart some workers logger.warning("Restarting UI and VimBroker workers!") with self.appliance.ssh_client as ssh: # Blow off the Vim brokers and UI workers ssh.run_rails_command("\"(MiqVimBrokerWorker.all + MiqUiWorker.all).each &:kill\"") logger.info("Waiting for web UI to come back alive.") sleep(10) # Give it some rest self.appliance.wait_for_web_ui() self.appliance.browser.quit_browser() self.appliance.browser.open_browser(url_key=self.obj.appliance.server.address()) self.go(_tries, *args, **go_kwargs) # Same with rails errors view = br.widgetastic.create_view(ErrorView) rails_e = view.get_rails_error() if rails_e is not None: logger.warning("Page was blocked by rails error, renavigating.") logger.error(rails_e) # RHEL7 top does not know -M and -a logger.debug('Top CPU consumers:') logger.debug(store.current_appliance.ssh_client.run_command( 'top -c -b -n1 | head -30').output) logger.debug('Top Memory consumers:') logger.debug(store.current_appliance.ssh_client.run_command( 'top -c -b -n1 -o "%MEM" | head -30').output) # noqa logger.debug('Managed known Providers:') logger.debug( '%r', [prov.key for prov in store.current_appliance.managed_known_providers]) self.appliance.browser.quit_browser() self.appliance.browser.open_browser() self.go(_tries, *args, **go_kwargs) # If there is a rails error past this point, something is really awful # Set this to True in the handlers below to trigger a browser restart recycle = False # Set this to True in handlers to restart evmserverd on the appliance # Includes recycling so you don't need to specify recycle = False restart_evmserverd = False try: self.log_message( "Invoking {}, with {} and {}".format(fn.func_name, args, kwargs), level="debug") return fn(*args, **kwargs) except (KeyboardInterrupt, ValueError): # KeyboardInterrupt: Don't block this while navigating raise except UnexpectedAlertPresentException: if _tries == 1: # There was an alert, accept it and try again br.widgetastic.handle_alert(wait=0) self.go(_tries, *args, **go_kwargs) else: # There was still an alert when we tried again, shoot the browser in the head logger.debug('Unxpected alert, recycling browser') recycle = True except (ErrorInResponseException, InvalidSwitchToTargetException): # Unable to switch to the browser at all, need to recycle logger.info('Invalid browser state, recycling browser') recycle = True except exceptions.CFMEExceptionOccured as e: # We hit a Rails exception logger.info('CFME Exception occured') logger.exception(e) recycle = True except exceptions.CannotContinueWithNavigation as e: # The some of the navigation steps cannot succeed logger.info('Cannot continue with navigation due to: {}; ' 'Recycling browser'.format(str(e))) recycle = True except (NoSuchElementException, InvalidElementStateException, WebDriverException, StaleElementReferenceException) as e: from cfme.web_ui import cfme_exception as cfme_exc # To prevent circular imports # First check - if jquery is not found, there can be also another # reason why this happened so do not put the next branches in elif if isinstance(e, WebDriverException) and "jQuery" in str(e): # UI failed in some way, try recycling the browser logger.exception( "UI failed in some way, jQuery not found, (probably) recycling the browser.") recycle = True # If the page is blocked, then recycle... # TODO .modal-backdrop.fade.in catches the 'About' modal resulting in nav loop if ( br.widgetastic.is_displayed("//div[@id='blocker_div' or @id='notification']") or br.widgetastic.is_displayed(".modal-backdrop.fade.in")): logger.warning("Page was blocked with blocker div, recycling.") recycle = True elif cfme_exc.is_cfme_exception(): logger.exception("CFME Exception before force navigate started!: {}".format( cfme_exc.cfme_exception_text())) recycle = True elif br.widgetastic.is_displayed("//body/h1[normalize-space(.)='Proxy Error']"): # 502 logger.exception("Proxy error detected. Killing browser and restarting evmserverd.") req = br.widgetastic.elements("/html/body/p[1]//a") req = br.widgetastic.text(req[0]) if req else "No request stated" reason = br.widgetastic.elements("/html/body/p[2]/strong") reason = br.widgetastic.text(reason[0]) if reason else "No reason stated" logger.info("Proxy error: {} / {}".format(req, reason)) restart_evmserverd = True elif br.widgetastic.is_displayed("//body[./h1 and ./p and ./hr and ./address]"): # 503 and similar sort of errors title = br.widgetastic.text("//body/h1") body = br.widgetastic.text("//body/p") logger.exception("Application error {}: {}".format(title, body)) sleep(5) # Give it a little bit of rest recycle = True elif br.widgetastic.is_displayed("//body/div[@class='dialog' and ./h1 and ./p]"): # Rails exception detection logger.exception("Rails exception before force navigate started!: %r:%r at %r", br.widgetastic.text("//body/div[@class='dialog']/h1"), br.widgetastic.text("//body/div[@class='dialog']/p"), getattr(manager.browser, 'current_url', "error://dead-browser") ) recycle = True elif br.widgetastic.elements("//ul[@id='maintab']/li[@class='inactive']") and not\ br.widgetastic.elements("//ul[@id='maintab']/li[@class='active']/ul/li"): # If upstream and is the bottom part of menu is not displayed logger.exception("Detected glitch from BZ#1112574. HEADSHOT!") recycle = True elif not self.obj.appliance.server.logged_in(): # Session timeout or whatever like that, login screen appears. logger.exception("Looks like we are logged out. Try again.") recycle = True else: logger.error("Could not determine the reason for failing the navigation. " + " Reraising. Exception: {}".format(str(e))) logger.debug(store.current_appliance.ssh_client.run_command( 'systemctl status evmserverd').output) raise if restart_evmserverd: logger.info("evmserverd restart requested") self.appliance.restart_evm_service() self.appliance.wait_for_web_ui() self.go(_tries, *args, **go_kwargs) if recycle or restart_evmserverd: self.appliance.browser.quit_browser() logger.debug('browser killed on try {}'.format(_tries)) # If given a "start" nav destination, it won't be valid after quitting the browser self.go(_tries, *args, **go_kwargs)
def check_for_badness(self, fn, _tries, nav_args, *args, **kwargs): if getattr(fn, '_can_skip_badness_test', False): # self.log_message('Op is a Nop! ({})'.format(fn.__name__)) return if self.VIEW: self.view.flush_widget_cache() go_kwargs = kwargs.copy() go_kwargs.update(nav_args) self.appliance.browser.open_browser() self.appliance.browser.widgetastic.dismiss_any_alerts() # check for MiqQE javascript patch on first try and patch the appliance if necessary if self.appliance.is_miqqe_patch_candidate and not self.appliance.miqqe_patch_applied: self.appliance.patch_with_miqqe() self.appliance.browser.quit_browser() _tries -= 1 self.go(_tries, *args, **go_kwargs) br = self.appliance.browser try: br.widgetastic.execute_script('miqSparkleOff();', silent=True) except: # Diaper OK (mfalesni) # miqSparkleOff undefined, so it's definitely off. pass # Check if the page is blocked with blocker_div. If yes, let's headshot the browser right # here if ( br.widgetastic.is_displayed("//div[@id='blocker_div' or @id='notification']") or br.widgetastic.is_displayed(".modal-backdrop.fade.in")): logger.warning("Page was blocked with blocker div on start of navigation, recycling.") self.appliance.browser.quit_browser() self.go(_tries, *args, **go_kwargs) # Check if modal window is displayed if (br.widgetastic.is_displayed( "//div[contains(@class, 'modal-dialog') and contains(@class, 'modal-lg')]")): logger.warning("Modal window was open; closing the window") br.widgetastic.click( "//button[contains(@class, 'close') and contains(@data-dismiss, 'modal')]") # Check if jQuery present try: br.widgetastic.execute_script("jQuery", silent=True) except Exception as e: if "jQuery" not in str(e): logger.error("Checked for jQuery but got something different.") logger.exception(e) # Restart some workers logger.warning("Restarting UI and VimBroker workers!") with self.appliance.ssh_client as ssh: # Blow off the Vim brokers and UI workers ssh.run_rails_command("\"(MiqVimBrokerWorker.all + MiqUiWorker.all).each &:kill\"") logger.info("Waiting for web UI to come back alive.") sleep(10) # Give it some rest self.appliance.wait_for_web_ui() self.appliance.browser.quit_browser() self.appliance.browser.open_browser() self.go(_tries, *args, **go_kwargs) # Same with rails errors rails_e = get_rails_error() if rails_e is not None: logger.warning("Page was blocked by rails error, renavigating.") logger.error(rails_e) # RHEL7 top does not know -M and -a logger.debug('Top CPU consumers:') logger.debug(store.current_appliance.ssh_client.run_command( 'top -c -b -n1 | head -30').output) logger.debug('Top Memory consumers:') logger.debug(store.current_appliance.ssh_client.run_command( 'top -c -b -n1 -o "%MEM" | head -30').output) # noqa logger.debug('Managed known Providers:') logger.debug( '%r', [prov.key for prov in store.current_appliance.managed_known_providers]) self.appliance.browser.quit_browser() self.appliance.browser.open_browser() self.go(_tries, *args, **go_kwargs) # If there is a rails error past this point, something is really awful # Set this to True in the handlers below to trigger a browser restart recycle = False # Set this to True in handlers to restart evmserverd on the appliance # Includes recycling so you don't need to specify recycle = False restart_evmserverd = False from cfme import login try: self.log_message( "Invoking {}, with {} and {}".format(fn.func_name, args, kwargs), level="debug") return fn(*args, **kwargs) except (KeyboardInterrupt, ValueError): # KeyboardInterrupt: Don't block this while navigating raise except UnexpectedAlertPresentException: if _tries == 1: # There was an alert, accept it and try again br.widgetastic.handle_alert(wait=0) self.go(_tries, *args, **go_kwargs) else: # There was still an alert when we tried again, shoot the browser in the head logger.debug('Unxpected alert, recycling browser') recycle = True except (ErrorInResponseException, InvalidSwitchToTargetException): # Unable to switch to the browser at all, need to recycle logger.info('Invalid browser state, recycling browser') recycle = True except exceptions.CFMEExceptionOccured as e: # We hit a Rails exception logger.info('CFME Exception occured') logger.exception(e) recycle = True except exceptions.CannotContinueWithNavigation as e: # The some of the navigation steps cannot succeed logger.info('Cannot continue with navigation due to: {}; ' 'Recycling browser'.format(str(e))) recycle = True except (NoSuchElementException, InvalidElementStateException, WebDriverException, StaleElementReferenceException) as e: from cfme.web_ui import cfme_exception as cfme_exc # To prevent circular imports # First check - if jquery is not found, there can be also another # reason why this happened so do not put the next branches in elif if isinstance(e, WebDriverException) and "jQuery" in str(e): # UI failed in some way, try recycling the browser logger.exception( "UI failed in some way, jQuery not found, (probably) recycling the browser.") recycle = True # If the page is blocked, then recycle... if ( br.widgetastic.is_displayed("//div[@id='blocker_div' or @id='notification']") or br.widgetastic.is_displayed(".modal-backdrop.fade.in")): logger.warning("Page was blocked with blocker div, recycling.") recycle = True elif cfme_exc.is_cfme_exception(): logger.exception("CFME Exception before force navigate started!: {}".format( cfme_exc.cfme_exception_text())) recycle = True elif br.widgetastic.is_displayed("//body/h1[normalize-space(.)='Proxy Error']"): # 502 logger.exception("Proxy error detected. Killing browser and restarting evmserverd.") req = br.widgetastic.elements("/html/body/p[1]//a") req = br.widgetastic.text(req[0]) if req else "No request stated" reason = br.widgetastic.elements("/html/body/p[2]/strong") reason = br.widgetastic.text(reason[0]) if reason else "No reason stated" logger.info("Proxy error: {} / {}".format(req, reason)) restart_evmserverd = True elif br.widgetastic.is_displayed("//body[./h1 and ./p and ./hr and ./address]"): # 503 and similar sort of errors title = br.widgetastic.text("//body/h1") body = br.widgetastic.text("//body/p") logger.exception("Application error {}: {}".format(title, body)) sleep(5) # Give it a little bit of rest recycle = True elif br.widgetastic.is_displayed("//body/div[@class='dialog' and ./h1 and ./p]"): # Rails exception detection logger.exception("Rails exception before force navigate started!: %r:%r at %r", br.widgetastic.text("//body/div[@class='dialog']/h1"), br.widgetastic.text("//body/div[@class='dialog']/p"), getattr(manager.browser, 'current_url', "error://dead-browser") ) recycle = True elif br.widgetastic.elements("//ul[@id='maintab']/li[@class='inactive']") and not\ br.widgetastic.elements("//ul[@id='maintab']/li[@class='active']/ul/li"): # If upstream and is the bottom part of menu is not displayed logger.exception("Detected glitch from BZ#1112574. HEADSHOT!") recycle = True elif not login.logged_in(): # Session timeout or whatever like that, login screen appears. logger.exception("Looks like we are logged out. Try again.") recycle = True else: logger.error("Could not determine the reason for failing the navigation. " + " Reraising. Exception: {}".format(str(e))) logger.debug(store.current_appliance.ssh_client.run_command( 'systemctl status evmserverd').output) raise if restart_evmserverd: logger.info("evmserverd restart requested") self.appliance.restart_evm_service() self.appliance.wait_for_web_ui() self.go(_tries, *args, **go_kwargs) if recycle or restart_evmserverd: self.appliance.browser.quit_browser() logger.debug('browser killed on try {}'.format(_tries)) # If given a "start" nav destination, it won't be valid after quitting the browser self.go(_tries, *args, **go_kwargs)
def force_navigate(page_name, _tries=0, *args, **kwargs): """force_navigate(page_name) Given a page name, attempt to navigate to that page no matter what breaks. Args: page_name: Name a page from the current :py:data:`ui_navigate.nav_tree` tree to navigate to. """ if _tries > 2: # Need at least three tries: # 1: login_admin handles an alert or CannotContinueWithNavigation appears. # 2: Everything should work. If not, NavigationError. raise exceptions.NavigationError(page_name) if "context" in kwargs: if not isinstance(kwargs["context"], ContextWrapper) and isinstance( kwargs["context"], dict): kwargs["context"] = ContextWrapper(kwargs["context"]) _tries += 1 logger.debug('force_navigate to %s, try %d' % (page_name, _tries)) # circular import prevention: cfme.login uses functions in this module from cfme import login # Import the top-level nav menus for convenience from cfme.web_ui import menu # browser fixture should do this, but it's needed for subsequent calls ensure_browser_open() # Clear any running "spinnies" try: execute_script('miqSparkleOff();') except: # Diaper OK (mfalesni) # miqSparkleOff undefined, so it's definitely off. pass # Set this to True in the handlers below to trigger a browser restart recycle = False # remember the current user, if any current_user = login.current_user() # Check if the page is blocked with blocker_div. If yes, let's headshot the browser right here if ( is_displayed("//div[@id='blocker_div' or @id='notification']", _no_deeper=True) or is_displayed(".modal-backdrop.fade.in", _no_deeper=True)): logger.warning("Page was blocked with blocker div on start of navigation, recycling.") quit() kwargs.pop("start", None) force_navigate("dashboard") # Start fresh # Check if jQuery present try: execute_script("jQuery") except Exception as e: if "jQuery" not in str(e): logger.error("Checked for jQuery but got something different.") logger.exception(e) # Restart some workers logger.warning("Restarting UI and VimBroker workers!") with store.current_appliance.ssh_client() as ssh: # Blow off the Vim brokers and UI workers ssh.run_rails_command("\"(MiqVimBrokerWorker.all + MiqUiWorker.all).each &:kill\"") logger.info("Waiting for web UI to come back alive.") sleep(10) # Give it some rest store.current_appliance.wait_for_web_ui() quit() ensure_browser_open() kwargs.pop("start", None) force_navigate("dashboard") # And start fresh # Same with rails errors rails_e = get_rails_error() if rails_e is not None: logger.warning("Page was blocked by rails error, renavigating.") logger.error(rails_e) logger.debug('Top CPU consumers:') logger.debug(store.current_appliance.ssh_client().run_command( 'top -c -b -n1 -M | head -30').output) logger.debug('Top Memory consumers:') logger.debug(store.current_appliance.ssh_client().run_command( 'top -c -b -n1 -M -a | head -30').output) logger.debug('Managed Providers:') logger.debug(store.current_appliance.managed_providers) quit() # Refresh the session, forget loaded summaries, ... kwargs.pop("start", None) ensure_browser_open() menu.nav.go_to("dashboard") # If there is a rails error past this point, something is really awful def _login_func(): if not current_user: # default to admin user login.login_admin() else: # we recycled and want to log back in login.login(current_user.username, current_user.password) try: try: # What we'd like to happen... _login_func() except WebDriverException as e: if "jquery" not in str(e).lower(): raise # Something unknown happened logger.info("Seems we got a non-CFME page (blank or screwed up) so killing the browser") quit() ensure_browser_open() # And try it again _login_func() # If this failed, no help with that :/ logger.info('Navigating to %s' % page_name) menu.nav.go_to(page_name, *args, **kwargs) except (KeyboardInterrupt, ValueError): # KeyboardInterrupt: Don't block this while navigating # ValueError: ui_navigate.go_to can't handle this page, give up raise except UnexpectedAlertPresentException: if _tries == 1: # There was an alert, accept it and try again handle_alert(wait=0) force_navigate(page_name, _tries, *args, **kwargs) else: # There was still an alert when we tried again, shoot the browser in the head logger.debug('Unxpected alert, recycling browser') recycle = True except (ErrorInResponseException, InvalidSwitchToTargetException): # Unable to switch to the browser at all, need to recycle logger.info('Invalid browser state, recycling browser') recycle = True except exceptions.CFMEExceptionOccured as e: # We hit a Rails exception logger.info('CFME Exception occured') logger.exception(e) recycle = True except exceptions.CannotContinueWithNavigation as e: # The some of the navigation steps cannot succeed logger.info('Cannot continue with navigation due to: %s; Recycling browser' % str(e)) recycle = True except (NoSuchElementException, InvalidElementStateException, WebDriverException) as e: from cfme.web_ui import cfme_exception as cfme_exc # To prevent circular imports # First check - if jquery is not found, there can be also another reason why this happened # so do not put the next branches in elif if isinstance(e, WebDriverException) and "jQuery" in str(e): # UI failed in some way, try recycling the browser logger.exception( "UI failed in some way, jQuery not found, (probably) recycling the browser.") recycle = True # If the page is blocked, then recycle... if ( is_displayed("//div[@id='blocker_div' or @id='notification']", _no_deeper=True) or is_displayed(".modal-backdrop.fade.in", _no_deeper=True)): logger.warning("Page was blocked with blocker div, recycling.") recycle = True elif cfme_exc.is_cfme_exception(): logger.exception("CFME Exception before force_navigate started!: `{}`".format( cfme_exc.cfme_exception_text() )) recycle = True elif is_displayed("//body[./h1 and ./p and ./hr and ./address]", _no_deeper=True): # 503 and similar sort of errors title = text("//body/h1") body = text("//body/p") logger.exception("Application error '{}': {}".format(title, body)) sleep(5) # Give it a little bit of rest recycle = True elif is_displayed("//body/div[@class='dialog' and ./h1 and ./p]", _no_deeper=True): # Rails exception detection logger.exception("Rails exception before force_navigate started!: {}:{} at {}".format( text("//body/div[@class='dialog']/h1").encode("utf-8"), text("//body/div[@class='dialog']/p").encode("utf-8"), current_url() )) recycle = True elif elements("//ul[@id='maintab']/li[@class='inactive']") and not\ elements("//ul[@id='maintab']/li[@class='active']/ul/li"): # If upstream and is the bottom part of menu is not displayed logger.exception("Detected glitch from BZ#1112574. HEADSHOT!") recycle = True else: logger.error("Could not determine the reason for failing the navigation. " + " Reraising. Exception: %s" % str(e)) logger.debug(store.current_appliance.ssh_client().run_command( 'service evmserverd status').output) raise if recycle: browser().quit() # login.current_user() will be retained for next login logger.debug('browser killed on try %d' % _tries) # If given a "start" nav destination, it won't be valid after quitting the browser kwargs.pop("start", None) force_navigate(page_name, _tries, *args, **kwargs)
def force_navigate(page_name, _tries=0, *args, **kwargs): """force_navigate(page_name) Given a page name, attempt to navigate to that page no matter what breaks. Args: page_name: Name a page from the current :py:data:`ui_navigate.nav_tree` tree to navigate to. """ if _tries > 2: # Need at least three tries: # 1: login_admin handles an alert or CannotContinueWithNavigation appears. # 2: Everything should work. If not, NavigationError. raise exceptions.NavigationError(page_name) if "context" in kwargs: if not isinstance(kwargs["context"], ContextWrapper) and isinstance( kwargs["context"], dict): kwargs["context"] = ContextWrapper(kwargs["context"]) _tries += 1 logger.debug('force_navigate to %s, try %d' % (page_name, _tries)) # circular import prevention: cfme.login uses functions in this module from cfme import login # Import the top-level nav menus for convenience from cfme.web_ui import menu # browser fixture should do this, but it's needed for subsequent calls ensure_browser_open() # Clear any running "spinnies" try: execute_script('miqSparkleOff();') except: # Diaper OK (mfalesni) # miqSparkleOff undefined, so it's definitely off. pass # Set this to True in the handlers below to trigger a browser restart recycle = False # remember the current user, if any current_user = login.current_user() # Check if the page is blocked with blocker_div. If yes, let's headshot the browser right here if ( is_displayed("//div[@id='blocker_div' or @id='notification']", _no_deeper=True) or is_displayed(".modal-backdrop.fade.in", _no_deeper=True)): logger.warning("Page was blocked with blocker div on start of navigation, recycling.") quit() kwargs.pop("start", None) force_navigate("dashboard") # Start fresh # Check if modal window is displayed if (is_displayed( "//div[contains(@class, 'modal-dialog') and contains(@class, 'modal-lg')]", _no_deeper=True)): logger.warning("Modal window was open; closing the window") click("//button[contains(@class, 'close') and contains(@data-dismiss, 'modal')]") # Check if jQuery present try: execute_script("jQuery") except Exception as e: if "jQuery" not in str(e): logger.error("Checked for jQuery but got something different.") logger.exception(e) # Restart some workers logger.warning("Restarting UI and VimBroker workers!") with store.current_appliance.ssh_client as ssh: # Blow off the Vim brokers and UI workers ssh.run_rails_command("\"(MiqVimBrokerWorker.all + MiqUiWorker.all).each &:kill\"") logger.info("Waiting for web UI to come back alive.") sleep(10) # Give it some rest store.current_appliance.wait_for_web_ui() quit() ensure_browser_open() kwargs.pop("start", None) force_navigate("dashboard") # And start fresh # Same with rails errors rails_e = get_rails_error() if rails_e is not None: logger.warning("Page was blocked by rails error, renavigating.") logger.error(rails_e) logger.debug('Top CPU consumers:') logger.debug(store.current_appliance.ssh_client.run_command( 'top -c -b -n1 -M | head -30').output) logger.debug('Top Memory consumers:') logger.debug(store.current_appliance.ssh_client.run_command( 'top -c -b -n1 -M -a | head -30').output) logger.debug('Managed Providers:') logger.debug(store.current_appliance.managed_providers) quit() # Refresh the session, forget loaded summaries, ... kwargs.pop("start", None) ensure_browser_open() menu.nav.go_to("dashboard") # If there is a rails error past this point, something is really awful def _login_func(): if not current_user: # default to admin user login.login_admin() else: # we recycled and want to log back in login.login(current_user.username, current_user.password) try: try: # What we'd like to happen... _login_func() except WebDriverException as e: if "jquery" not in str(e).lower(): raise # Something unknown happened logger.info("Seems we got a non-CFME page (blank or screwed up) so killing the browser") quit() ensure_browser_open() # And try it again _login_func() # If this failed, no help with that :/ logger.info('Navigating to %s' % page_name) menu.nav.go_to(page_name, *args, **kwargs) except (KeyboardInterrupt, ValueError): # KeyboardInterrupt: Don't block this while navigating # ValueError: ui_navigate.go_to can't handle this page, give up raise except UnexpectedAlertPresentException: if _tries == 1: # There was an alert, accept it and try again handle_alert(wait=0) force_navigate(page_name, _tries, *args, **kwargs) else: # There was still an alert when we tried again, shoot the browser in the head logger.debug('Unxpected alert, recycling browser') recycle = True except (ErrorInResponseException, InvalidSwitchToTargetException): # Unable to switch to the browser at all, need to recycle logger.info('Invalid browser state, recycling browser') recycle = True except exceptions.CFMEExceptionOccured as e: # We hit a Rails exception logger.info('CFME Exception occured') logger.exception(e) recycle = True except exceptions.CannotContinueWithNavigation as e: # The some of the navigation steps cannot succeed logger.info('Cannot continue with navigation due to: %s; Recycling browser' % str(e)) recycle = True except (NoSuchElementException, InvalidElementStateException, WebDriverException) as e: from cfme.web_ui import cfme_exception as cfme_exc # To prevent circular imports # First check - if jquery is not found, there can be also another reason why this happened # so do not put the next branches in elif if isinstance(e, WebDriverException) and "jQuery" in str(e): # UI failed in some way, try recycling the browser logger.exception( "UI failed in some way, jQuery not found, (probably) recycling the browser.") recycle = True # If the page is blocked, then recycle... if ( is_displayed("//div[@id='blocker_div' or @id='notification']", _no_deeper=True) or is_displayed(".modal-backdrop.fade.in", _no_deeper=True)): logger.warning("Page was blocked with blocker div, recycling.") recycle = True elif cfme_exc.is_cfme_exception(): logger.exception("CFME Exception before force_navigate started!: `{}`".format( cfme_exc.cfme_exception_text() )) recycle = True elif is_displayed("//body[./h1 and ./p and ./hr and ./address]", _no_deeper=True): # 503 and similar sort of errors title = text("//body/h1") body = text("//body/p") logger.exception("Application error '{}': {}".format(title, body)) sleep(5) # Give it a little bit of rest recycle = True elif is_displayed("//body/div[@class='dialog' and ./h1 and ./p]", _no_deeper=True): # Rails exception detection logger.exception("Rails exception before force_navigate started!: {}:{} at {}".format( text("//body/div[@class='dialog']/h1").encode("utf-8"), text("//body/div[@class='dialog']/p").encode("utf-8"), current_url() )) recycle = True elif elements("//ul[@id='maintab']/li[@class='inactive']") and not\ elements("//ul[@id='maintab']/li[@class='active']/ul/li"): # If upstream and is the bottom part of menu is not displayed logger.exception("Detected glitch from BZ#1112574. HEADSHOT!") recycle = True else: logger.error("Could not determine the reason for failing the navigation. " + " Reraising. Exception: %s" % str(e)) logger.debug(store.current_appliance.ssh_client.run_command( 'service evmserverd status').output) raise if recycle: browser().quit() # login.current_user() will be retained for next login logger.debug('browser killed on try %d' % _tries) # If given a "start" nav destination, it won't be valid after quitting the browser kwargs.pop("start", None) force_navigate(page_name, _tries, *args, **kwargs)
def do_nav(self, _tries=0): # Set this to True in the handlers below to trigger a browser restart recycle = False # Set this to True in handlers to restart evmserverd on the appliance # Includes recycling so you don't need to specify recycle = False restart_evmserverd = False current_user = store.user from cfme import login def _login_func(): if not current_user: # default to admin user login.login_admin() else: # we recycled and want to log back in login.login(store.user) try: try: # What we'd like to happen... _login_func() except WebDriverException as e: if "jquery" not in str(e).lower(): raise # Something unknown happened logger.info("Seems we got a non-CFME page (blank " "or screwed up) so killing the browser") quit() ensure_browser_open() # And try it again _login_func() # If this failed, no help with that :/ self.step() except (KeyboardInterrupt, ValueError): # KeyboardInterrupt: Don't block this while navigating # ValueError: ui_navigate.go_to can't handle this page, give up raise except UnexpectedAlertPresentException: if _tries == 1: # There was an alert, accept it and try again handle_alert(wait=0) self.go(_tries) else: # There was still an alert when we tried again, shoot the browser in the head logger.debug('Unxpected alert, recycling browser') recycle = True except (ErrorInResponseException, InvalidSwitchToTargetException): # Unable to switch to the browser at all, need to recycle logger.info('Invalid browser state, recycling browser') recycle = True except exceptions.CFMEExceptionOccured as e: # We hit a Rails exception logger.info('CFME Exception occured') logger.exception(e) recycle = True except exceptions.CannotContinueWithNavigation as e: # The some of the navigation steps cannot succeed logger.info('Cannot continue with navigation due to: {}; ' 'Recycling browser'.format(str(e))) recycle = True except (NoSuchElementException, InvalidElementStateException, WebDriverException, StaleElementReferenceException) as e: from cfme.web_ui import cfme_exception as cfme_exc # To prevent circular imports # First check - if jquery is not found, there can be also another # reason why this happened so do not put the next branches in elif if isinstance(e, WebDriverException) and "jQuery" in str(e): # UI failed in some way, try recycling the browser logger.exception( "UI failed in some way, jQuery not found, (probably) recycling the browser.") recycle = True # If the page is blocked, then recycle... if ( is_displayed("//div[@id='blocker_div' or @id='notification']", _no_deeper=True) or is_displayed(".modal-backdrop.fade.in", _no_deeper=True)): logger.warning("Page was blocked with blocker div, recycling.") recycle = True elif cfme_exc.is_cfme_exception(): logger.exception("CFME Exception before force_navigate started!: {}".format( cfme_exc.cfme_exception_text())) recycle = True elif is_displayed("//body/h1[normalize-space(.)='Proxy Error']"): # 502 logger.exception("Proxy error detected. Killing browser and restarting evmserverd.") req = elements("/html/body/p[1]//a") req = text(req[0]) if req else "No request stated" reason = elements("/html/body/p[2]/strong") reason = text(reason[0]) if reason else "No reason stated" logger.info("Proxy error: {} / {}".format(req, reason)) restart_evmserverd = True elif is_displayed("//body[./h1 and ./p and ./hr and ./address]", _no_deeper=True): # 503 and similar sort of errors title = text("//body/h1") body = text("//body/p") logger.exception("Application error {}: {}".format(title, body)) sleep(5) # Give it a little bit of rest recycle = True elif is_displayed("//body/div[@class='dialog' and ./h1 and ./p]", _no_deeper=True): # Rails exception detection logger.exception("Rails exception before force_navigate started!: %s:%s at %s", text("//body/div[@class='dialog']/h1").encode("utf-8"), text("//body/div[@class='dialog']/p").encode("utf-8"), browser().current_url ) recycle = True elif elements("//ul[@id='maintab']/li[@class='inactive']") and not\ elements("//ul[@id='maintab']/li[@class='active']/ul/li"): # If upstream and is the bottom part of menu is not displayed logger.exception("Detected glitch from BZ#1112574. HEADSHOT!") recycle = True elif not login.logged_in(): # Session timeout or whatever like that, login screen appears. logger.exception("Looks like we are logged out. Try again.") recycle = True else: logger.error("Could not determine the reason for failing the navigation. " + " Reraising. Exception: {}".format(str(e))) logger.debug(store.current_appliance.ssh_client.run_command( 'service evmserverd status').output) raise if restart_evmserverd: logger.info("evmserverd restart requested") store.current_appliance.restart_evm_service() store.current_appliance.wait_for_web_ui() if recycle or restart_evmserverd: browser().quit() # login.current_user() will be retained for next login logger.debug('browser killed on try {}'.format(_tries)) # If given a "start" nav destination, it won't be valid after quitting the browser self.go(_tries)
def do_nav(self, _tries=0, *args, **kwargs): # Set this to True in the handlers below to trigger a browser restart recycle = False # Set this to True in handlers to restart evmserverd on the appliance # Includes recycling so you don't need to specify recycle = False restart_evmserverd = False from cfme import login br = self.appliance.browser try: self.step(*args, **kwargs) except (KeyboardInterrupt, ValueError): # KeyboardInterrupt: Don't block this while navigating raise except UnexpectedAlertPresentException: if _tries == 1: # There was an alert, accept it and try again br.widgetastic.handle_alert(wait=0) self.go(_tries) else: # There was still an alert when we tried again, shoot the browser in the head logger.debug('Unxpected alert, recycling browser') recycle = True except (ErrorInResponseException, InvalidSwitchToTargetException): # Unable to switch to the browser at all, need to recycle logger.info('Invalid browser state, recycling browser') recycle = True except exceptions.CFMEExceptionOccured as e: # We hit a Rails exception logger.info('CFME Exception occured') logger.exception(e) recycle = True except exceptions.CannotContinueWithNavigation as e: # The some of the navigation steps cannot succeed logger.info('Cannot continue with navigation due to: {}; ' 'Recycling browser'.format(str(e))) recycle = True except (NoSuchElementException, InvalidElementStateException, WebDriverException, StaleElementReferenceException) as e: from cfme.web_ui import cfme_exception as cfme_exc # To prevent circular imports # First check - if jquery is not found, there can be also another # reason why this happened so do not put the next branches in elif if isinstance(e, WebDriverException) and "jQuery" in str(e): # UI failed in some way, try recycling the browser logger.exception( "UI failed in some way, jQuery not found, (probably) recycling the browser.") recycle = True # If the page is blocked, then recycle... if ( br.widgetastic.is_displayed("//div[@id='blocker_div' or @id='notification']") or br.widgetastic.is_displayed(".modal-backdrop.fade.in")): logger.warning("Page was blocked with blocker div, recycling.") recycle = True elif cfme_exc.is_cfme_exception(): logger.exception("CFME Exception before force navigate started!: {}".format( cfme_exc.cfme_exception_text())) recycle = True elif br.widgetastic.is_displayed("//body/h1[normalize-space(.)='Proxy Error']"): # 502 logger.exception("Proxy error detected. Killing browser and restarting evmserverd.") req = br.widgetastic.elements("/html/body/p[1]//a") req = br.widgetastic.text(req[0]) if req else "No request stated" reason = br.widgetastic.elements("/html/body/p[2]/strong") reason = br.widgetastic.text(reason[0]) if reason else "No reason stated" logger.info("Proxy error: {} / {}".format(req, reason)) restart_evmserverd = True elif br.widgetastic.is_displayed("//body[./h1 and ./p and ./hr and ./address]"): # 503 and similar sort of errors title = br.widgetastic.text("//body/h1") body = br.widgetastic.text("//body/p") logger.exception("Application error {}: {}".format(title, body)) sleep(5) # Give it a little bit of rest recycle = True elif br.widgetastic.is_displayed("//body/div[@class='dialog' and ./h1 and ./p]"): # Rails exception detection logger.exception("Rails exception before force navigate started!: %r:%r at %r", br.widgetastic.text("//body/div[@class='dialog']/h1"), br.widgetastic.text("//body/div[@class='dialog']/p"), getattr(manager.browser, 'current_url', "error://dead-browser") ) recycle = True elif br.widgetastic.elements("//ul[@id='maintab']/li[@class='inactive']") and not\ br.widgetastic.elements("//ul[@id='maintab']/li[@class='active']/ul/li"): # If upstream and is the bottom part of menu is not displayed logger.exception("Detected glitch from BZ#1112574. HEADSHOT!") recycle = True elif not login.logged_in(): # Session timeout or whatever like that, login screen appears. logger.exception("Looks like we are logged out. Try again.") recycle = True else: logger.error("Could not determine the reason for failing the navigation. " + " Reraising. Exception: {}".format(str(e))) logger.debug(store.current_appliance.ssh_client.run_command( 'service evmserverd status').output) raise if restart_evmserverd: logger.info("evmserverd restart requested") self.appliance.restart_evm_service() self.appliance.wait_for_web_ui() if recycle or restart_evmserverd: self.appliance.browser.quit_browser() logger.debug('browser killed on try {}'.format(_tries)) # If given a "start" nav destination, it won't be valid after quitting the browser self.go(_tries)