Source code for sw.utils

import os, time, traceback
from selenium.common.exceptions import *
from const import *



[docs]def loadScript( driver, js ): """Creates a new script object and appends it to the header. :Parameters: * :ref:`driver <common-params>` * **js** -- URL to a JavaScript file that will be inserted and loaded on this page. :return: None """ driver.execute_script_async( \ "var script = document.createElement( 'script' ); \ script.type = 'text/javascript'; \ script.src = '" + js + "'; \ document.getElementsByTagName('head')[0].appendChild( script );" )
[docs]def exists( driver, element, type, **kwargs ): """Checks if an element exists with the WebDriver functions. Catches and handles exceptions if it doesn't. Previously there was an issue where the find_element_by... would wait for 15 seconds to find the element, but that has been resolved. If an element is in the DOM, does a final check to see if it is displayed and available. :Parameters: * :ref:`driver <common-params>` * :ref:`element <common-params>` * :ref:`type <common-params>` :Kwargs: * :ref:`lightConfirm <common-params>` * :ref:`cache <common-params>` * :ref:`url <common-params>` :return: Boolean if doesn't exist, :py:class:`~selenium.webdriver.remote.webelement.WebElement` if it does. """ lightConfirm = kwargs.get( 'lightConfirm', driver.child.options.get( 'lightconfirm', False ) ) cache = kwargs.get( 'cache', driver.child.options.get( 'cache', True ) ) current_url = kwargs.get( 'url', driver.current_url ) e = None if cache: e = driver.child.cache.get( current_url, id=element, type=type ) if e is None: try: if type == "id": e = driver.find_element_by_id( element ) elif type == "name": e = driver.find_element_by_name( element ) elif type == "xpath": e = driver.find_element_by_xpath( element ) elif type == "link_text": e = driver.find_element_by_link_text( element ) elif type == "css_selector": e = driver.find_element_by_css_selector( element ) except Exception as e: driver.child.logMsg( ''.join( [ "Error received when checking for existence: ", str( e ) ] ), DEBUG ) return False if cache: driver.child.cache.add( current_url, e, id=element, type=type ) if lightConfirm or ( isDisplayed( e ) and isEnabled( e ) ): return e return False
[docs]def sleepwait( driver, element, type, **kwargs ): """The original brainchild of this wrapper, this function simply checks if an element exists( ) and sleeps until timeout for it. It always returns something, even if it fails. :Parameters: * :ref:`driver <common-params>` * :ref:`element <common-params>` * :ref:`type <common-params>` :Kwargs: * :ref:`die <common-params>` -- This is only passed to subfunctions. :py:func:`~util.waitToDisappear` never ends the script if something does not disappear. * :ref:`timeout <common-params>` * :ref:`thinkTime <common-params>` * :ref:`cache <common-params>` * :ref:`url <common-params>` * :ref:`lightConfirm <common-params>` :return: Boolean if doesn't exist, :py:class:`~selenium.webdriver.remote.webelement.WebElement` if it does. """ start = time.time( ) timeout = kwargs.get( 'timeout', 15 ) lightConfirm = kwargs.get( 'lightConfirm', driver.child.options.get( 'lightconfirm', False ) ) cache = kwargs.get( 'cache', driver.child.options.get( 'cache', True ) ) url = kwargs.get( 'url', driver.current_url ) die = kwargs.get( 'die', True ) thinkTime = kwargs.get( 'thinkTime', driver.child.sleepTime ) driver.child.display( DISP_WAIT ) e = exists( driver, element, type, url=url, cache=cache, lightConfirm=lightConfirm ) if not e: driver.child.logMsg( ''.join( [ "Beginning wait for element \"", element, "\" of type \"", type, "\"." ] ), NOTICE ) while not e: if time.time( ) - start > timeout: break time.sleep( thinkTime ) e = exists( driver, element, type, url=url, cache=cache, lightConfirm=lightConfirm ) else: driver.child.display( DISP_GOOD ) return e else: driver.child.display( DISP_GOOD ) return e driver.child.logMsg( ''.join( [ "Element will not be found on page \"", driver.current_url, "\"." ] ), CRITICAL, locals=locals( ) ) if die: driver.child.logMsg( "Child will now terminate.", CRITICAL, locals=locals( ) ) raise TimeoutException( ''.join( [ "Element ", element, " not found within timeout ", str(timeout), "s." ] ) ) # Wait to be killed return False
[docs]def sendKeys( driver, element, type, text ): """Drop in, faster replacement for :py:func:`~selenium.webdriver.remote.webelement.WebElement.send_keys`. Currently only supports fields with an `id` or `name` identifier. :Parameters: * :ref:`driver <common-params>` * :ref:`element <common-params>` * :ref:`type <common-params>` * **text** -- The text to type into the element. :return: None """ sleepwait( driver, element, type, lightConfirm=True ) if type == "id": driver.execute_script( ''.join( [ "document.getElementById( '", element, "' ).value = '", text, "'" ] ) ) elif type == "name": driver.execute_script( ''.join( [ "document.getElementsByName( '", element, "' )[0].value = '", text, "'" ] ) )
[docs]def waitToDisappear( driver, element, **kwargs ): """Waits for an element to disappear from the page. Useful for transparent overlays that appear routinely as those block all input on the page (which angers WebDriver). Optionally can wait for an element to reappear and call itself again to wait longer. :Parameters: * :ref:`driver <common-params>` * :ref:`element <common-params>` :Kwargs: * :ref:`type <common-params>` (*"id"*) * :ref:`die <common-params>` -- This is only passed to subfunctions. :py:func:`~util.waitToDisappear` never ends the script if something does not disappear. :(wait-related): * :ref:`timeout <common-params>` (*60*) * :ref:`thinkTime <common-params>` (*2*) * **stayGone** (*0*) -- Amount of time in seconds we wait, checking that the element is really gone. * **waitForElement** (*True*) -- If the element doesn't initially exist on the page, this controls if waitToDisappear waits for it first. * **waitTimeout** (*3*) -- Number of seconds we wait for the element to appear. If the element doesn't exist after this timeout, the function returns. :(internal): * :ref:`cache <common-params>` * **offset** (*0*) -- Used internally so timeout still applies to recursive calls. This offsets the next timeout by the amount of time waited in the previous call. * **recur** (*False*) -- Internally used to not print to the log if this function calls itself again. :return: None """ waitForElement = kwargs.get( 'waitForElement', True ) waitTimeout = kwargs.get( 'waitTimeout', 3 ) stayGone = kwargs.get( 'stayGone', 0 ) thinkTime = kwargs.get( 'thinkTime', driver.child.sleepTime*2 ) recur = kwargs.get( 'recur', False ) timeout = kwargs.get( 'timeout', 60 ) type = kwargs.get( 'type', 'id' ) offset = kwargs.get( 'offset', 0 ) cache = kwargs.get( 'cache', True ) die = kwargs.get( 'die', True ) start = time.time( ) - offset url = driver.current_url # Do an initial wait for our element to appear. Any confirmation is confirmation (light). if waitForElement: kwargs['die'] = False # Override die just in case element doesn't exist kwargs['timeout'] = waitTimeout sleepwait( driver, element, type, **kwargs ) if not exists( driver, element, type, **kwargs ): driver.child.logMsg( ''.join( [ "In waitToDisappear \"", element, "\" was never there to begin with." ] ) ) # If we should wait for it and it's not here... leave. return else: if not recur: driver.child.logMsg( ''.join( [ "Waiting for \"", element, "\"." ] ), INFO ) driver.child.display( STATI_WAIT ) time.sleep( thinkTime ) kwargs['die'] = die kwargs['timeout'] = timeout while exists( driver, element, type, **kwargs ): if time.time( ) - start > timeout: driver.child.logMsg( ''.join( [ "Element did not disappear within ", str( timeout ), "s, timed out." ] ), CRITICAL, locals=locals( ) ) if die: driver.child.logMsg( "Child will now terminate.", CRITICAL, locals=locals( ) ) raise TimeoutException( ''.join( [ "Element ", element, " didn't disappear within timeout", str(timeout), "s." ] ) ) break #this skips the else time.sleep( thinkTime ) else: driver.child.logMsg( ''.join( [ "Element \"", element, "\" disappeared!" ] ), INFO ) if stayGone > 0: w = stayGone + time.time( ) while w - time.time( ) >= 0: if exists( driver, element, type, **kwargs ): driver.child.logMsg( "Element came back!" ) kwargs['offset'] = time.time( ) - start kwargs['recur'] = True waitToDisappear( driver, element, **kwargs ) time.sleep( thinkTime ) driver.child.display( DISP_GOOD )
[docs]def isDisplayed( e ): """Does a check to see if the element is displayed while catching exceptions safely. Often when the script needs to see if an element is displayed, it isn't even on the page. This can kill the program. :param e: An active :py:class:`~selenium.webdriver.remote.webelement.WebElement` that will be checked if it is displayed. :return: Boolean where True if the element is displayed and False if it is not. """ try: if e.is_displayed( ): return True except: return False return False
[docs]def isEnabled( e ): """Does a check to see if an element is enabled while capturing exceptions safely. Often when the script needs to see if an element is enabled, it isn't. This normally kills the script and is undesireable. :param e: An active :py:class:`~selenium.webdriver.remote.webelement.WebElement` that will be checked if it is enabled (can type into / click). :return: Boolean where True if the element is enabled and False if it is not. """ try: if e.is_enabled( ): return True except: return False return False # Should extract a variable from driver.current_url, then plop its value on to url and redirect. #def urlExtractRedirect( driver, variable, value ): # url = driver.current_url # # driver.child.logMsg( "urlExtractRedirect\nBEFORE: " + url ) # # r = re.compile( r"(?P<start>[\?\&])%s=(?P<value>[^\&]+)$" % variable ) # # if not url.match( r ): # driver.logMsg( "WARNING: URL Doesn't appear to contain a variable in this manner: ?" + variable + "= or &" + variable + "=" ) # return # # re.sub( r, "\g<start>" + variable + "=" + value, url ) # # driver.logMsg( "AFTER: " + url ) # driver.get( url )