Skip to content

Commit

Permalink
REFACTOR: either-like handling of screenshot failures
Browse files Browse the repository at this point in the history
  • Loading branch information
yashaka committed Jul 15, 2024
1 parent 18cd27b commit c43fbc8
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 32 deletions.
2 changes: 0 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,6 @@ should we even refactor out them from Condition and move to Match only?

### TODO: rename all conditions inside match.py so match can be fully used instead be + have #530

### TODO: consider implementing either_res_or just for demo...

### Deprecated conditions

- `be.present` in favor of `be.present_in_dom`
Expand Down
20 changes: 18 additions & 2 deletions selene/common/fp.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import functools
import inspect
from typing import TypeVar, Callable, Any, Tuple, Optional
from typing_extensions import TypeVar, Callable, Any, Tuple, Optional

# T = TypeVar('T', bound=Callable[..., Any])
T = TypeVar('T')
Expand Down Expand Up @@ -63,6 +62,23 @@ def identity(it: T) -> T:
return it


# todo: what about decorator? like:
# > res, maybe_failure = _either(res=func, or_=Exception)(*args, **kwargs)
# over
# > res, maybe_failure = _either_res_or(Exception, func, *args, **kwargs)
# todo: support exception_type as tuple of exception types
# todo: make generic-aware version of this function,
# that knows the type of failure
# that knows the type of fn res
def _either_res_or(
exception_type, fn: Callable, /, *args, **kwargs
) -> Tuple[Any, Optional[Exception]]:
try:
return fn(*args, **kwargs), None
except exception_type as failure:
return ..., failure


def pipe(*functions) -> Optional[Callable[[Any], Any]]:
"""
pipes functions one by one in the provided order
Expand Down
42 changes: 14 additions & 28 deletions selene/core/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -1427,30 +1427,21 @@ def _inject_screenshot_and_page_source_pre_hooks(self, hook):
# TODO: consider moving hooks to class methods accepting config as argument
# or refactor somehow to eliminate all times defining hook fns
def save_and_log_screenshot(error: TimeoutException) -> Exception:
path = None
failure_reason: WebDriverException | None = None
try:
# todo: consider changing _save_screenshot_strategy to be Either-like
# TODO: consider refactoring to be Either-monad-like
# so we can eliminate try..except clauses
# > path, maybe_failure = either_res_or(
# > WebDriverException
# > self._save_screenshot_strategy,
# > self,
# > )
path = self._save_screenshot_strategy(self) # type: ignore
except WebDriverException as reason:
failure_reason = reason
# todo: consider changing _save_screenshot_strategy to be Either-like
# > path, maybe_failure = self._save_screenshot_strategy(self)
path, maybe_failure = fp._either_res_or(
WebDriverException, self._save_screenshot_strategy, self
)
return TimeoutException(
error.msg
# todo: should we just skip logging screenshot at all when failure?
+ '\nScreenshot: '
+ (
self._format_path_as_uri(path)
if path and not failure_reason
if path and not maybe_failure
else 'cannot be saved because of: {name}: {message}'.format(
name=failure_reason.__class__.__name__,
message=getattr(failure_reason, "msg", str(failure_reason)),
name=maybe_failure.__class__.__name__,
message=getattr(maybe_failure, "msg", str(maybe_failure)),
)
)
)
Expand All @@ -1464,23 +1455,18 @@ def save_and_log_page_source(error: TimeoutException) -> Exception:
else self._generate_filename(suffix='.html')
)

path = None
failure_reason: WebDriverException | None = None
try:
# TODO: consider refactoring to be Either-monad-like
# so we can eliminate try..except clauses
path = self._save_page_source_strategy(self, filename)
except WebDriverException as reason:
failure_reason = reason
path, maybe_failure = fp._either_res_or(
WebDriverException, self._save_screenshot_strategy, self
)
return TimeoutException(
error.msg
+ '\nPageSource: '
+ (
self._format_path_as_uri(path)
if path and not failure_reason
if path and not maybe_failure
else 'cannot be saved because of: {name}: {message}'.format(
name=failure_reason.__class__.__name__,
message=getattr(failure_reason, "msg", str(failure_reason)),
name=maybe_failure.__class__.__name__,
message=getattr(maybe_failure, "msg", str(maybe_failure)),
)
)
)
Expand Down

0 comments on commit c43fbc8

Please sign in to comment.