Skip to content

Commit

Permalink
Provide internal unfind method to emulate inverse find
Browse files Browse the repository at this point in the history
This method is needed to separate internal method calls within the
region class since certain public methods like `wait` and the
previously unfind emulating `wait_vanish` could be overridden while
`find` and the resulting `_unfind` are typically not to preserve
behaviors from all internal calls by other public region methods.

For instance to better illustrate this - consider a case where we
would like to catch `FindError` and `NotFindError` exceptions and
convert them to test failures or other specialized exceptions. If
one overrides `wait` and `wait_vanish` then `click_vanish` or e.g.
`press_expect` will not catch the right exception types and guibot
will not retry its human-like UI control attempts.
  • Loading branch information
pevogam committed Dec 13, 2024
1 parent be4a367 commit 1be0df5
Showing 1 changed file with 22 additions and 7 deletions.
29 changes: 22 additions & 7 deletions guibot/region.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,16 +599,20 @@ def wait(self, target: str | Target, timeout: int = 30) -> "Match":
log.info("Waiting for %s", target)
return self.find(target, timeout)

def wait_vanish(self, target: str | Target, timeout: int = 30) -> "Region":
def _unfind(self, target: str | Target, timeout: int = 30) -> "Region":
"""
Wait for a target to disappear (be unmatched) with a given timeout as failing tolerance.
Emulate waiting for a vanishing target.
:param target: target to look for
:param timeout: timeout before giving up
:returns: self
:raises: :py:class:`errors.NotFindError` if match is still found
This method is meant to be as internal as `find()` but with the inverse
meaning. It is not meant to be used on the same level of abstraction
as `wait_vanish()` just like `find()` is not meant to be used on the same
level of abstraction as `wait()`.
"""
log.info("Waiting for %s to vanish", target)
expires = time.time() + timeout
while time.time() < expires:
if self.exists(target, 0) is None:
Expand All @@ -620,6 +624,17 @@ def wait_vanish(self, target: str | Target, timeout: int = 30) -> "Region":
# target is still there
raise NotFindError(target)

def wait_vanish(self, target: str | Target, timeout: int = 30) -> "Region":
"""
Wait for a target to disappear (be unmatched) with a given timeout as failing tolerance.
:param target: target to look for
:param timeout: timeout before giving up
:returns: self
"""
log.info("Waiting for %s to vanish", target)
return self._unfind(target, timeout)

def idle(self, timeout: int) -> "Region":
"""
Wait for a number of seconds and continue the nested call chain.
Expand Down Expand Up @@ -794,7 +809,7 @@ def click_expect(
log.info("Retrying the mouse click (%s of %s)", i + 1, retries)
self.click(click_image_or_location, modifiers=modifiers)
try:
return self.wait(expect_target, timeout)
return self.find(expect_target, timeout)
except FindError as error:
self.hover(Location(0, 0))
if i == retries - 1:
Expand Down Expand Up @@ -824,7 +839,7 @@ def click_vanish(
log.info("Retrying the mouse click (%s of %s)", i + 1, retries)
self.click(click_image_or_location, modifiers=modifiers)
try:
return self.wait_vanish(expect_target, timeout)
return self._unfind(expect_target, timeout)
except NotFindError as error:
self.hover(Location(0, 0))
if i == retries - 1:
Expand Down Expand Up @@ -1116,7 +1131,7 @@ def press_expect(
log.info("Retrying the key press (%s of %s)", i + 1, retries)
self.press_keys(keys)
try:
return self.wait(expect_target, timeout)
return self.find(expect_target, timeout)
except FindError as error:
if i == retries - 1:
raise error
Expand Down Expand Up @@ -1144,7 +1159,7 @@ def press_vanish(
log.info("Retrying the key press (%s of %s)", i + 1, retries)
self.press_keys(keys)
try:
return self.wait_vanish(expect_target, timeout)
return self._unfind(expect_target, timeout)
except NotFindError as error:
if i == retries - 1:
raise error
Expand Down

0 comments on commit 1be0df5

Please sign in to comment.