Source code for nerodia.wait.wait

import re

import nerodia
from .timer import Timer

try:
    from re import Pattern
except ImportError:
    from re import _pattern_type as Pattern


[docs]class Wait(object): INTERVAL = 0.1 timer = Timer() # Access timer implementation in use
[docs] @classmethod def until(cls, method=None, timeout=None, message=None, interval=None, object=None): """ Waits until the method evaluates to True or times out :param method: method to run, typically lambda :param object: object to evaluate method with :param timeout: time to wait :type timeout: float :param message: message to raise if timeout is exceeded :type message: str :param interval: time to wait between each check :type interval: float :Example: Wait.until(lambda: browser.text_field(name='abrakadbra').present) """ timeout = timeout or nerodia.default_timeout result = cls._run_with_timer(timeout, interval, method, object, until=True) if result: return result raise TimeoutError(cls._message_for(timeout, object, message))
[docs] @classmethod def until_not(cls, method=None, timeout=None, message=None, interval=None, object=None): """ Waits while the method evaluates to True or times out :param method: method to run, typically lambda :param object: object to evaluate method with :param timeout: time to wait :type timeout: float :param message: message to raise if timeout is exceeded :type message: str :param interval: time to wait between each check :type interval: float :Example: Wait.until_not(lambda: browser.text_field(name='abrakadbra').present) """ timeout = timeout or nerodia.default_timeout result = cls._run_with_timer(timeout, interval, method, object, until=False) if result: return result raise TimeoutError(cls._message_for(timeout, object, message))
whilst = until_not @classmethod def _message_for(cls, timeout, object, message): if callable(message): message = message(object) err = 'timed out after {} seconds'.format(timeout) if message: err += ', {}'.format(message) return err @classmethod def _run_with_timer(cls, timeout, interval, method, object, until=True): if timeout == 0: return method(object) if object is not None else method() else: interval = interval or cls.INTERVAL result = cls.timer.wait(timeout, method, interval=interval, object=object, expected=until) return result
[docs]class Waitable(object):
[docs] def wait_until(self, method=None, timeout=None, message=None, interval=None, object=None, **kwargs): """ Waits until the condition is True :param method: method to run, typically lambda :param object: object to evaluate method with :param timeout: time to wait :type timeout: int :param message: message to raise if timeout is exceeded :type message: str :param interval: time to wait between each check :type interval: float :Example: browser.text_field(name='new_user_first_name').wait_until(lambda x: x.present).click browser.text_field(name='new_user_first_name').wait_until(name='new_user_first_name').click """ if not message: def msg(obj): return 'waiting for true condition on {}'.format(obj) message = msg if object is None: object = self # TODO: Consider throwing argument error for mixing block & options method = self._create_closure(kwargs, method) Wait.until(method=method, timeout=timeout, message=message, interval=interval, object=object) return self
[docs] def wait_until_not(self, method=None, timeout=None, message=None, interval=None, object=None, **kwargs): """ Waits while the condition is True :param method: method to run, typically lambda :param object: object to evaluate method with :param timeout: time to wait :type timeout: int :param message: message to raise if timeout is exceeded :type message: str :param interval: time to wait between each check :type interval: float :Example: browser.wait_until_not(lambda x: not x.exists, timeout=2)] browser.wait_until_not(title='no') """ if not message: def msg(obj): return 'waiting for false condition on {}'.format(obj) message = msg if object is None: object = self # TODO: Consider throwing argument error for mixing block & options method = self._create_closure(kwargs, method, until=False) Wait.until_not(method=method, timeout=timeout, message=message, interval=interval, object=object) return self
[docs] def wait_until_present(self, timeout=None, interval=None, message=None): """ Waits until the element is present :param timeout: time to wait :type timeout: int :param interval: time to wait between each check :type interval: float :param message: message error message for when times out :type message: str :Example: browser.text_field(name='new_user_first_name').wait_until_present() """ nerodia.logger.deprecate('{}#wait_until_present'.format(self.__class__.__name__), '{}#wait_until(method=lambda e: e.present)', ids=['wait_until_present']) if not message: def msg(obj): return 'waiting for element {} to become present'.format(obj) message = msg return self.wait_until(method=lambda x: x.present, timeout=timeout, interval=interval, message=message, element_reset=True)
[docs] def wait_until_not_present(self, timeout=None, interval=None, message=None): """ Waits while the element is present :param timeout: time to wait :type timeout: int :param interval: time to wait between each check :type interval: float :param message: message error message for when times out :type message: str :Example: browser.text_field(name='abrakadbra').wait_until_not_present """ nerodia.logger.deprecate('{}#wait_until_not_present'.format(self.__class__.__name__), '{}#wait_until_not(method=lambda e: e.present)', ids=['wait_until_not_present']) if not message: def msg(obj): return 'waiting for element {} not to be present'.format(obj) message = msg return self.wait_until_not(method=lambda x: x.present, timeout=timeout, interval=interval, message=message, element_reset=True)
def _create_closure(self, obj, method=None, until=True): from nerodia.elements.element import Element def func(*args): if isinstance(self, Element) and obj.pop('element_reset', None): self.reset() return (not obj or self._match_attributes(obj, until)()) and (not method or method(*args)) return func def _match_attributes(self, obj, until=True): from ..elements.element import Element def check(key): expected = obj.get(key) if isinstance(self, Element) and not hasattr(self, key): actual = self.get_attribute(key) else: attr = getattr(self, key) actual = attr() if callable(attr) else attr if isinstance(expected, Pattern): return re.search(expected, actual) is not None else: return expected == actual def func(*args): truthy = all if until else any return truthy(check(key) for key in obj) return func
[docs]class TimeoutError(Exception): pass