diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index f504541..c3db195 100644 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -7,7 +7,10 @@ We follow `Semantic Versions `_. ******************************************************************************* - Update diagrams with `mermaid `__ -- Add invocation **inv docs.serve" to run docs on localhost +- Add invocation **inv docs.serve** to run docs on localhost +- Add auto-scroll to element before click +- Add page class name to ``PageDidNotLoadedError`` +- Add method ``contains()`` to ``XPathLocator`` for search by contained text Backwards incompatible changes in 0.7.0 ------------------------------------------------------------------------------- diff --git a/pomcorn/element.py b/pomcorn/element.py index 87a6c98..04f18cf 100644 --- a/pomcorn/element.py +++ b/pomcorn/element.py @@ -285,6 +285,7 @@ def select(self, value: str, only_visible: bool = True): def click( self, only_visible: bool = True, + scroll_to: bool = True, wait_until_clickable: bool = True, ): """Click on element. @@ -292,10 +293,13 @@ def click( Args: only_visible: Flag for viewing visible elements. If this is `True` (default), then this method will only get visible elements. + scroll_to: Whether to scroll to element before clicking or not. wait_until_clickable: Wait until the element is clickable before clicking, or not (default `True`). """ + if scroll_to: + self.scroll_to(only_visible=only_visible) if wait_until_clickable: self.wait_until_clickable() self.get_element(only_visible=only_visible).click() diff --git a/pomcorn/locators/base_locators.py b/pomcorn/locators/base_locators.py index fb9deda..2f28b17 100644 --- a/pomcorn/locators/base_locators.py +++ b/pomcorn/locators/base_locators.py @@ -121,11 +121,15 @@ def __init__(self, query: str): def __truediv__(self, other: XPathLocator) -> XPathLocator: """Override `/` operator to implement following XPath locators.""" - return XPathLocator(query=f"{self.query}/{other.related_query}") + return XPathLocator( + query=f"//{self.related_query}/{other.related_query}", + ) def __floordiv__(self, other: XPathLocator) -> XPathLocator: """Override `//` operator to implement nested XPath locators.""" - return XPathLocator(query=f"{self.query}//{other.related_query}") + return XPathLocator( + query=f"//{self.related_query}//{other.related_query}", + ) def __or__(self, other: XPathLocator) -> XPathLocator: r"""Override `|` operator to implement variant XPath locators. @@ -145,3 +149,19 @@ def __or__(self, other: XPathLocator) -> XPathLocator: def extend_query(self, extra_query: str) -> XPathLocator: """Return new XPathLocator with extended query.""" return XPathLocator(query=self.query + extra_query) + + def contains(self, text: str, exact: bool = False) -> XPathLocator: + """Return new XPathLocator with search on contained text. + + This is shortcut for the commonly used + `.extend_query(f"[contains(., '{text}')])`. + + Args: + text: The text that should be inside the tag. + exact: Specify whether the text being searched must match exactly. + By default, the search is based on a partial match. + + """ + partial_query = f"[contains(., '{text}')]" + exact_query = f"[./text()='{text}']" + return self.extend_query(exact_query if exact else partial_query) diff --git a/pomcorn/page.py b/pomcorn/page.py index 4cabc74..9dc54c2 100644 --- a/pomcorn/page.py +++ b/pomcorn/page.py @@ -122,8 +122,9 @@ def wait_until_loaded(self) -> None: self.wait.until(lambda _: self.check_page_is_loaded()) except TimeoutException: raise PageDidNotLoadedError( - f"Page didn't loaded in {self.wait_timeout} seconds! " - "Didn't wait for `True` from `check_page_is_loaded` method.", + f"Page `{self.__class__}` didn't loaded in " + f"{self.wait_timeout} seconds! Didn't wait for `True` from " + "`check_page_is_loaded` method.", ) def navigate(self, url: str) -> None: