diff --git a/screenpy_selenium/resolutions/is_clickable.py b/screenpy_selenium/resolutions/is_clickable.py index ad5746a..ff5ed06 100644 --- a/screenpy_selenium/resolutions/is_clickable.py +++ b/screenpy_selenium/resolutions/is_clickable.py @@ -4,7 +4,7 @@ from typing import TYPE_CHECKING -from screenpy.resolutions.base_resolution import BaseResolution +from screenpy import beat from .custom_matchers import is_clickable_element @@ -12,7 +12,7 @@ from .custom_matchers.is_clickable_element import IsClickableElement -class IsClickable(BaseResolution): +class IsClickable: """Match on a clickable element. Examples:: @@ -20,9 +20,11 @@ class IsClickable(BaseResolution): the_actor.should(See.the(Element(LOGIN_BUTTON), IsClickable())) """ - matcher: IsClickableElement - line = "clickable" - matcher_function = is_clickable_element + def describe(self) -> str: + """Describe the Resolution's expectation.""" + return "clickable" - def __init__(self) -> None: # pylint: disable=useless-super-delegation - super().__init__() + @beat("... hoping it's clickable") + def resolve(self) -> IsClickableElement: + """Produce the Matcher to make the assertion.""" + return is_clickable_element() diff --git a/tests/test_resolutions.py b/tests/test_resolutions.py index 2502168..2733198 100644 --- a/tests/test_resolutions.py +++ b/tests/test_resolutions.py @@ -1,15 +1,13 @@ from __future__ import annotations +import logging from dataclasses import dataclass -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any import pytest from hamcrest.core.string_description import StringDescription from screenpy_selenium import IsClickable, IsInvisible, IsPresent, IsVisible -from screenpy_selenium.resolutions.custom_matchers.is_clickable_element import ( - IsClickableElement, -) from screenpy_selenium.resolutions.custom_matchers.is_invisible_element import ( IsInvisibleElement, ) @@ -23,7 +21,7 @@ from .useful_mocks import get_mocked_element if TYPE_CHECKING: - from screenpy import BaseResolution + from hamcrest.core.matcher import Matcher from selenium.webdriver.remote.webelement import WebElement @@ -36,7 +34,7 @@ class ExpectedDescriptions: def _assert_descriptions( - obj: BaseResolution, element: WebElement, expected: ExpectedDescriptions + obj: Matcher[Any], element: WebElement, expected: ExpectedDescriptions ) -> None: describe_to = StringDescription() describe_match = StringDescription() @@ -64,9 +62,9 @@ def test_matches_a_clickable_element(self) -> None: element = get_mocked_element() element.is_enabled.return_value = True element.is_displayed.return_value = True - ic = IsClickable() + ic = IsClickable().resolve() - assert ic._matches(element) + assert ic.matches(element) def test_does_not_match_unclickable_element(self) -> None: invisible_element = get_mocked_element() @@ -76,7 +74,7 @@ def test_does_not_match_unclickable_element(self) -> None: invisible_element.is_enabled.return_value = True inactive_element.is_displayed.return_value = True inactive_element.is_enabled.return_value = False - ic = IsClickable() + ic = IsClickable().resolve() assert not ic._matches(None) # element was not found by Element() assert not ic._matches(invisible_element) @@ -90,14 +88,19 @@ def test_descriptions(self) -> None: describe_mismatch="was not enabled/clickable", describe_none="was not even present", ) + ic = IsClickable() - _assert_descriptions(IsClickable(), element, expected) + assert ic.describe() == "clickable" + _assert_descriptions(ic.resolve(), element, expected) - def test_type_hint(self) -> None: - ic = IsClickable() - annotation = ic.__annotations__["matcher"] - assert annotation == "IsClickableElement" - assert type(ic.matcher) == IsClickableElement + def test_beat_logging(self, caplog: pytest.LogCaptureFixture) -> None: + caplog.set_level(logging.INFO) + IsClickable().resolve() + + assert [r.msg for r in caplog.records] == [ + "... hoping it's clickable", + " => the element is enabled/clickable", + ] class TestIsVisible: