Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add small improvements #66

Merged
merged 4 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ We follow `Semantic Versions <https://semver.org/>`_.
*******************************************************************************

- Update diagrams with `mermaid <https://mermaid.js.org/intro/>`__
- 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
-------------------------------------------------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions pomcorn/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,17 +285,21 @@ 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.

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:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to change order of wait and click.
Consider case when button is not visible on a screen (need to scroll) and not clickable.
If wait condition will fail, it would be nice to make a screenshot to investigate issue later. But screenshot won't show desired button because scroll not applied yet

self.scroll_to(only_visible=only_visible)
if wait_until_clickable:
self.wait_until_clickable()
self.get_element(only_visible=only_visible).click()
Expand Down
24 changes: 22 additions & 2 deletions pomcorn/locators/base_locators.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)
5 changes: 3 additions & 2 deletions pomcorn/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down