def assert_matches_selector(self, *args, **kwargs): """ Asserts that the current node matches a given selector. :: node.assert_matches_selector("p#foo") node.assert_matches_selector("xpath", "//p[@id='foo']") It also accepts all options that :meth:`find_all` accepts, such as ``text`` and ``visible``. :: node.assert_matches_selector("li", text="Horse", visible=True) Args: *args: Variable length argument list for :class:`SelectorQuery`. **kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`. Returns: True Raises: ExpectationNotMet: If the selector does not match. """ query = SelectorQuery(*args, **kwargs) @self.synchronize(wait=query.wait) def assert_matches_selector(): result = query.resolve_for(self.query_scope) if self not in result: raise ExpectationNotMet("Item does not match the provided selector") return True return assert_matches_selector()
def assert_not_match_selector(self, *args, **kwargs): """ Asserts that the current node does not match a given selector. See :meth:`assert_matches_selector`. Args: *args: Variable length argument list for :class:`SelectorQuery`. **kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`. Returns: True Raises: ExpectationNotMet: If the selector matches. """ query = SelectorQuery(*args, **kwargs) @self.synchronize(wait=query.wait) def assert_not_match_selector(): result = query.resolve_for(self.query_scope) if self in result: raise ExpectationNotMet("Item matched the provided selector") return True return assert_not_match_selector()
def find_all(self, *args, **kwargs): """ Find all elements on the page matching the given selector and options. Both XPath and CSS expressions are supported, but Capybara does not try to automatically distinguish between them. The following statements are equivalent:: page.find_all("css", "a#person_123") page.find_all("xpath", "//a[@id='person_123']") If the type of selector is left out, Capybara uses :data:`capybara.default_selector`. It's set to ``"css"`` by default. :: page.find_all("a#person_123") capybara.default_selector = "xpath" page.find_all("//a[@id='person_123']") The set of found elements can further be restricted by specifying options. It's possible to select elements by their text or visibility:: page.find_all("a", text="Home") page.find_all("#menu li", visible=True) By default if no elements are found, an empty list is returned; however, expectations can be set on the number of elements to be found which will trigger Capybara's waiting behavior for the expectations to match. The expectations can be set using:: page.assert_selector("p#foo", count=4) page.assert_selector("p#foo", maximum=10) page.assert_selector("p#foo", minimum=1) page.assert_selector("p#foo", between=range(1, 11)) See :func:`capybara.result.Result.matches_count` for additional information about count matching. Args: *args: Variable length argument list for :class:`SelectorQuery`. **kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`. Returns: Result: A collection of found elements. Raises: ExpectationNotMet: The matched results did not meet the expected criteria. """ query = SelectorQuery(*args, **kwargs) @self.synchronize(wait=query.wait) def find_all(): result = query.resolve_for(self) if not result.matches_count: raise ExpectationNotMet(result.failure_message) return result return find_all()
def assert_selector(self, *args, **kwargs): """ Asserts that a given selector is on the page or a descendant of the current node. :: page.assert_selector("p#foo") By default it will check if the expression occurs at least once, but a different number can be specified. :: page.assert_selector("p.foo", count=4) This will check if the expression occurs exactly 4 times. See :meth:`find_all` for other available result size options. If a ``count`` of 0 is specified, it will behave like :meth:`assert_no_selector`; however, use of that method is preferred over this one. It also accepts all options that :meth:`find_all` accepts, such as ``text`` and ``visible``. :: page.assert_selector("li", text="Horse", visible=True) ``assert_selector`` can also accept XPath expressions generated by the ``xpath-py`` package:: from xpath import dsl as x page.assert_selector("xpath", x.descendant("p")) Args: *args: Variable length argument list for :class:`SelectorQuery`. **kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`. Returns: True Raises: ExpectationNotMet: The given selector did not match. """ query = SelectorQuery(*args, **kwargs) @self.synchronize(wait=query.wait) def assert_selector(): result = query.resolve_for(self) if not (result.matches_count and (len(result) > 0 or expects_none(query.options))): raise ExpectationNotMet(result.failure_message) return True return assert_selector()
def find(self, *args, **kwargs): """ Find an :class:`Element` based on the given arguments. ``find`` will raise an error if the element is not found. ``find`` takes the same options as :meth:`find_all`. :: page.find("#foo").find(".bar") page.find("xpath", "//div[contains(., 'bar')]") page.find("li", text="Quox").click_link("Delete") Args: *args: Variable length argument list for :class:`SelectorQuery`. **kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`. Returns: Element: The found element. Raises: Ambiguous: If more than one element matching element is found. ElementNotFound: If the element can't be found before time expires. """ query = SelectorQuery(*args, **kwargs) @self.synchronize(wait=query.wait) def find(): if query.match in ["prefer_exact", "smart"]: result = query.resolve_for(self, True) if len(result) == 0 and not query.exact: result = query.resolve_for(self, False) else: result = query.resolve_for(self) if query.match in ["one", "smart"] and len(result) > 1: raise Ambiguous( "Ambiguous match, found {count} elements matching {query}". format(count=len(result), query=query.description)) if len(result) == 0: raise ElementNotFound("Unable to find {0}".format( query.description)) element = result[0] element.allow_reload = True return element return find()
def assert_no_selector(self, *args, **kwargs): """ Asserts that a given selector is not on the page or a descendant of the current node. Usage is identical to :meth:`assert_selector`. Query options such as ``count``, ``minimum``, and ``between`` are considered to be an integral part of the selector. This will return True, for example, if a page contains 4 anchors but the query expects 5:: page.assert_no_selector("a", minimum=1) # Found, raises ExpectationNotMet page.assert_no_selector("a", count=4) # Found, raises ExpectationNotMet page.assert_no_selector("a", count=5) # Not Found, returns True Args: *args: Variable length argument list for :class:`SelectorQuery`. **kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`. Returns: True Raises: ExpectationNotMet: The given selector matched. """ query = SelectorQuery(*args, **kwargs) @self.synchronize(wait=query.wait) def assert_no_selector(): result = query.resolve_for(self) if result.matches_count and (len(result) > 0 or expects_none(query.options)): raise ExpectationNotMet(result.negative_failure_message) return True return assert_no_selector()
def find(self, *args, **kwargs): """ Find an :class:`Element` based on the given arguments. ``find`` will raise an error if the element is not found. ``find`` takes the same options as :meth:`find_all`. :: page.find("#foo").find(".bar") page.find("xpath", "//div[contains(., 'bar')]") page.find("li", text="Quox").click_link("Delete") Args: *args: Variable length argument list for :class:`SelectorQuery`. **kwargs: Arbitrary keyword arguments for :class:`SelectorQuery`. Returns: Element: The found element. Raises: Ambiguous: If more than one element matching element is found. ElementNotFound: If the element can't be found before time expires. """ return self._synchronized_resolve(SelectorQuery(*args, **kwargs))