def reset_password(): login.update_password(username, current_password, password) assert login.logged_in(), "password reset failed" login.logout() login.login(username, password) assert login.logged_in(), "password reset failed" login.logout()
def test_user_change_password(request): user = ac.User( name="user {}".format(fauxfactory.gen_alphanumeric()), credential=Credential( principal="user_principal_{}".format(fauxfactory.gen_alphanumeric()), secret="very_secret", verify_secret="very_secret" ), email="*****@*****.**", group=usergrp, ) user.create() request.addfinalizer(user.delete) request.addfinalizer(login.login_admin) login.logout() assert not login.logged_in() login.login(user.credential.principal, user.credential.secret) assert login.current_full_name() == user.name login.login_admin() with update(user): user.credential = Credential( principal=user.credential.principal, secret="another_very_secret", verify_secret="another_very_secret", ) login.logout() assert not login.logged_in() login.login(user.credential.principal, user.credential.secret) assert login.current_full_name() == user.name
def test_user_change_password(request): user = ac.User( name="user {}".format(fauxfactory.gen_alphanumeric()), credential=Credential(principal="user_principal_{}".format( fauxfactory.gen_alphanumeric()), secret="very_secret", verify_secret="very_secret"), email="*****@*****.**", group=usergrp, ) user.create() request.addfinalizer(user.delete) request.addfinalizer(login.login_admin) with user: assert not login.logged_in() login.login(user) assert login.current_full_name() == user.name login.login_admin() with update(user): user.credential = Credential( principal=user.credential.principal, secret="another_very_secret", verify_secret="another_very_secret", ) with user: assert not login.logged_in() login.login(user) assert login.current_full_name() == user.name
def test_verify_password_update(request): """ Tests that password changes are successful Warning: This will temporarily change the password for the default account. If you stop the tests unexpectedly, the password may not be reset to the default, making future logins based on the defaults unsuccessful until a manual reset of the password is done. If you need to manually reset the password, the current password should be the value of either new_password, username, or username + new_password. """ username = conf.credentials['default']['username'] password = conf.credentials['default']['password'] new_password = "******" current_password = password # Check that original login credentials work login.login(username, current_password) assert login.logged_in(), "yaml credentials are incorrect!" # Reset password once this function stops def reset_password(): login.update_password(username, current_password, password) assert login.logged_in(), "password reset failed" login.logout() login.login(username, password) assert login.logged_in(), "password reset failed" login.logout() request.addfinalizer(reset_password) # Simple update login.update_password(username, current_password, new_password) assert login.logged_in() current_password = new_password # Username as password login.update_password(username, current_password, username) assert login.logged_in() current_password = username # New password starts with old password login.update_password(username, current_password, current_password + new_password) assert login.logged_in() current_password = current_password + new_password
def test_verify_bad_password_update(): """ Tests that if any information on the password update form is incorrect that the system rejects the change attempt and does not update the login information """ username = conf.credentials['default']['username'] password = conf.credentials['default']['password'] new_password = "******" # Ensure original login credentials work login.login(username, password) assert login.logged_in(), "yaml credentials are incorrect!" # Incorrect original password login.update_password(username, password + "ThisPartIsWrong", new_password) assert login.flash.is_error(login.flash.get_messages()[0]) # New passwords don't match login.update_password(username, password, new_password, new_password + "3xtraCharacters") assert login.flash.is_error(login.flash.get_messages()[0]) # Empty new password field login.clear_fields() login.update_password(username, password, "", new_password) assert login.flash.is_error(login.flash.get_messages()[0]) # Empty new password verification field login.clear_fields() login.update_password(username, password, new_password, "") assert login.flash.is_error(login.flash.get_messages()[0]) # Reset password to same password login.clear_fields() login.update_password(username, password, password) assert login.flash.is_error(login.flash.get_messages()[0]) # Ensure original password still works login.close_password_update_form() login.login(username, password) assert login.logged_in(), "Password has been changed!"
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 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)
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 Providers:') logger.debug('%r', [prov.key for prov in store.current_appliance.managed_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)) 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( 'service evmserverd status').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)