def description(self): if isregex(self.expected_text): return "text matching {}".format(desc(self.expected_text)) elif self.options["exact_text"]: return "exact text {}".format(desc(self.expected_text)) else: return "text {}".format(desc(self.expected_text))
def __init__(self, query_type, expected_text=None, between=None, count=None, exact_text=False, maximum=None, minimum=None, wait=None): if expected_text is None: expected_text = query_type query_type = None if query_type is None: query_type = ("visible" if capybara.ignore_hidden_elements or capybara.visible_text_only else "all") assert query_type in VALID_QUERY_TYPE, \ "invalid option {query_type} for query_type, should be one of {valid_values}".format( query_type=desc(query_type), valid_values=", ".join(desc(VALID_QUERY_TYPE))) self.expected_text = (expected_text if isregex(expected_text) else normalize_text(expected_text)) self.query_type = query_type self.search_regexp = toregex(expected_text, exact=exact_text) self.options = { "between": between, "count": count, "exact_text": exact_text, "maximum": maximum, "minimum": minimum, "wait": wait} self.node = None self.actual_text = None self.count = None
def resolves_for(self, session): """ Returns whether this query resolves for the given session. Args: session (Session): The session for which this query should be executed. Returns: bool: Whether this query resolves. """ if self.url: self.actual_path = session.current_url else: result = urlparse(session.current_url) if self.only_path: self.actual_path = result.path else: request_uri = result.path if result.query: request_uri += "?{0}".format(result.query) self.actual_path = request_uri if isregex(self.expected_path): return self.expected_path.search(self.actual_path) else: return normalize_url(self.actual_path) == normalize_url( self.expected_path)
def _build_message(self, negated=""): verb = "match" if isregex(self.expected_title) else "include" return "expected {actual}{negated} to {verb} {expected}".format( actual=desc(self.actual_title), negated=negated, verb=verb, expected=desc(self.expected_title))
def __init__(self, expected_title, exact=False, wait=None): self.expected_title = (expected_title if isregex(expected_title) else normalize_text(expected_title)) self.actual_title = None self.search_regexp = toregex(expected_title, exact=exact) self.options = {"wait": wait}
def _build_message(self, negated=""): verb = "match" if isregex(self.expected_path) else "equal" return "expected {actual}{negated} to {verb} {expected}".format( actual=desc(self.actual_path), negated=negated, verb=verb, expected=desc(self.expected_path))
def href(node, href): if isregex(href): return bool(href.search(node["href"])) else: # For href element attributes, Selenium returns the full URL that would # be visited rather than the raw value in the source. So we use XPath. query = x.axis("self")[x.attr("href") == str_(href)] return node.has_selector("xpath", query)
def matches_filters(self, node): """ Returns whether the given node matches all filters. Args: node (Element): The node to evaluate. Returns: bool: Whether the given node matches. """ visible = self.visible if self.options["text"]: if isregex(self.options["text"]): regex = self.options["text"] elif self.exact_text is True: regex = re.compile(r"\A{}\Z".format( re.escape(self.options["text"]))) else: regex = toregex(self.options["text"]) text = normalize_text(node.all_text if visible == "all" else node.visible_text) if not regex.search(text): return False if isinstance(self.exact_text, (bytes_, str_)): regex = re.compile(r"\A{}\Z".format(re.escape(self.exact_text))) text = normalize_text(node.all_text if visible == "all" else node.visible_text) if not regex.search(text): return False if visible == "visible": if not node.visible: return False elif visible == "hidden": if node.visible: return False for name, query_filter in iter(self._query_filters.items()): if name in self.filter_options: if not query_filter.matches(node, self.filter_options[name]): return False elif query_filter.has_default: if not query_filter.matches(node, query_filter.default): return False if self.options["filter"] and not self.options["filter"](node): return False return True
def _find_modal(self, text=None, wait=None): wait = wait or capybara.default_max_wait_time try: alert = WebDriverWait(self.browser, wait).until(EC.alert_is_present()) regexp = toregex(text) if not regexp.search(alert.text): qualifier = "matching" if isregex(text) else "with" raise ModalNotFound("Unable to find modal dialog {0} {1}".format(qualifier, desc(text))) return alert except TimeoutException: raise ModalNotFound("Unable to find modal dialog")
def desc(value): """ str | List[str]: A normalized representation for a user-provided value. """ if isinstance(value, list): return map(desc, value) if isregex(value): value = value.pattern if isbytes(value): value = decode_bytes(value) return repr(value)
def toregex(text): """ Returns a compiled regular expression for the given text. Args: text (str | RegexObject): The text to match. Returns: RegexObject: A compiled regular expression that will match the text. """ return (text if isregex(text) else re.compile(re.escape(normalize_text(text))))
def desc(value): """ str | List[str]: A normalized representation for a user-provided value. """ if isinstance(value, list): return map(desc, value) if isregex(value): value = value.pattern if isbytes(value): value = decode_bytes(value) if PY2: if isstring(value): # In Python 2, strings (``unicode`` objects) represent as ``u'...'``, so ensure # the string is encoded (as a ``str`` object) for cleaner representation. value = encode_string(value) return repr(value)
def normalize_strings(value): if isinstance(value, list): value = [normalize_strings(e) for e in value] if isinstance(value, dict): value = {normalize_strings(k): normalize_strings(v) for k, v in iter(value.items())} if isregex(value): value = value.pattern if isbytes(value): value = decode_bytes(value) if PY2: if isstring(value): # In Python 2, strings (``unicode`` objects) represent as ``u'...'``, so ensure # the string is encoded (as a ``str`` object) for cleaner representation. value = encode_string(value) return value
def toregex(text, exact=False): """ Returns a compiled regular expression for the given text. Args: text (str | RegexObject): The text to match. exact (bool, optional): Whether the generated regular expression should match exact strings. Defaults to False. Returns: RegexObject: A compiled regular expression that will match the text. """ if isregex(text): return text escaped = re.escape(normalize_text(text)) if exact: escaped = r"\A{}\Z".format(escaped) return re.compile(escaped)
def description(self): if isregex(self.expected_text): return "text matching {}".format(desc(self.expected_text)) else: return "text {}".format(desc(self.expected_text))
def __init__(self, expected_title): self.expected_title = (expected_title if isregex(expected_title) else normalize_text(expected_title)) self.actual_title = None self.search_regexp = toregex(expected_title)
def value(node, value): if isregex(value): return bool(value.search(node.value)) else: return node.value == value