Skip to content

API reference

This page provides a complete reference for all public APIs in selenium-expect.

Quick navigation

expect(target, ...)

Create an assertion for the given target. Dispatches to the appropriate assertion class based on the target's type.

Supported targets

Target type Assertion class Example
WebElement ExpectElement expect(element).to_be_visible()
WebDriver ExpectDriver expect(driver).to_have_title("Page")
list[WebElement] ExpectList expect(elements).to_have_count(5)
Alert ExpectAlert expect(alert).to_have_text("Confirm?")
Select ExpectSelect expect(select).to_have_value("opt1")
ShadowRoot ExpectShadow expect(shadow).to_have_element(By.ID, "x")
WebDriver + by/value LocatorExpect expect(driver, by=By.ID, value="x").to_be_visible()

Parameters

Parameter Type Default Description
target Any The object to assert on
by str None Locator strategy (for locator-based expect)
value str None Locator value (for locator-based expect)
locator tuple[str, str] None (by, value) tuple shorthand
message str None Custom message for error output
soft bool False Enable soft assertion mode
timeout float None Override default timeout
polling float \| list[float] None Override default polling

selenium_expect._expect.Expect

Callable expect dispatcher with attached utilities.

Use expect(target) to create assertions, expect.poll(fn) for retry-based polling, and expect.configure(...) for pre-configured variants.

Source code in selenium_expect/_expect.py
class Expect:
    """Callable expect dispatcher with attached utilities.

    Use ``expect(target)`` to create assertions, ``expect.poll(fn)`` for
    retry-based polling, and ``expect.configure(...)`` for pre-configured
    variants.
    """

    def __call__(
        self,
        target: Any,
        /,
        *,
        message: str | None = None,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
        soft: bool | None = None,
        config: ExpectConfig | None = None,
        by: str | None = None,
        value: str | None = None,
        locator: tuple[str, str] | None = None,
    ) -> AssertionMixin:
        """Create an expect assertion for the given target.

        Dispatches to the appropriate assertion class via ``ASSERTION_REGISTRY``
        based on the target's type.

        If ``by`` and ``value`` are provided, a ``LocatorExpect`` is created
        that re-finds the element on each poll cycle.

        Alternatively, ``locator=(By.ID, 'foo')`` can be used as a tuple
        shorthand for ``by=..., value=...``.
        """
        if locator is not None:
            if by is not None or value is not None:
                raise ValueError("Cannot use both 'locator' and 'by/value' arguments")
            by, value = locator

        if (by is not None) != (value is not None):
            raise ValueError("Must provide both 'by' and 'value', or neither")

        if by is not None and value is not None:
            from selenium_expect._locator import LocatorExpect

            if not isinstance(target, WebDriver):
                raise TypeError("expect() with by/value requires a WebDriver target")

            effective_config = config if config is not None else get_config()
            if timeout is not None or polling is not None or soft is not None:
                overrides: dict[str, Any] = {}
                if timeout is not None:
                    overrides["timeout"] = normalize_timeout(timeout)
                if polling is not None:
                    if isinstance(polling, list):
                        overrides["polling_intervals"] = polling
                    else:
                        overrides["polling_interval"] = polling
                if soft is not None:
                    overrides["soft_mode"] = soft
                effective_config = effective_config.replace(**overrides)

            return LocatorExpect(
                driver=target,
                by=by,
                value=value,
                config=effective_config,
                message=message,
            )

        if target is None:
            raise TypeError("expect() does not support None as target")

        type_name = _resolve_target_type(target)
        cls = ASSERTION_REGISTRY.get(type_name)
        if cls is None:
            raise TypeError(f"expect() does not support target type '{type_name}'")

        assertion_cls = cast(type[AssertionMixin], cls)

        effective_config = config if config is not None else get_config()

        if timeout is not None or polling is not None or soft is not None:
            cfg_overrides: dict[str, Any] = {}
            if timeout is not None:
                cfg_overrides["timeout"] = normalize_timeout(timeout)
            if polling is not None:
                if isinstance(polling, list):
                    cfg_overrides["polling_intervals"] = polling
                else:
                    cfg_overrides["polling_interval"] = polling
            if soft is not None:
                cfg_overrides["soft_mode"] = soft
            effective_config = effective_config.replace(**cfg_overrides)

        return assertion_cls(target=target, config=effective_config, message=message)

    def poll(
        self,
        fn: Callable[[], Any],
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
        config: ExpectConfig | None = None,
    ) -> PollAssertion:
        """Create a ``PollAssertion`` for retry-based assertions on *fn*.

        Usage::

            expect.poll(lambda: driver.execute_script("return document.readyState"))
                .to_equal("complete")
        """
        return PollAssertion(fn, timeout=timeout, polling=polling, config=config)

    def configure(self, **defaults: Any) -> Callable[..., AssertionMixin]:
        """Create a pre-configured expect variant.

        Returns a callable that behaves like ``expect()`` with *defaults*
        pre-applied. Explicit kwargs from the caller override the defaults.

        Usage::

            fast_expect = expect.configure(timeout=1.0, polling=0.1)
            fast_expect(el).to_be_visible()
        """

        def _configured_expect(
            target: Any,
            /,
            **overrides: Any,
        ) -> AssertionMixin:
            merged: dict[str, Any] = {**defaults, **overrides}
            return self(target, **merged)

        return _configured_expect

__call__

__call__(target: Any, /, *, message: str | None = None, timeout: float | None = None, polling: float | list[float] | None = None, soft: bool | None = None, config: ExpectConfig | None = None, by: str | None = None, value: str | None = None, locator: tuple[str, str] | None = None) -> AssertionMixin

Create an expect assertion for the given target.

Dispatches to the appropriate assertion class via ASSERTION_REGISTRY based on the target's type.

If by and value are provided, a LocatorExpect is created that re-finds the element on each poll cycle.

Alternatively, locator=(By.ID, 'foo') can be used as a tuple shorthand for by=..., value=....

Source code in selenium_expect/_expect.py
def __call__(
    self,
    target: Any,
    /,
    *,
    message: str | None = None,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
    soft: bool | None = None,
    config: ExpectConfig | None = None,
    by: str | None = None,
    value: str | None = None,
    locator: tuple[str, str] | None = None,
) -> AssertionMixin:
    """Create an expect assertion for the given target.

    Dispatches to the appropriate assertion class via ``ASSERTION_REGISTRY``
    based on the target's type.

    If ``by`` and ``value`` are provided, a ``LocatorExpect`` is created
    that re-finds the element on each poll cycle.

    Alternatively, ``locator=(By.ID, 'foo')`` can be used as a tuple
    shorthand for ``by=..., value=...``.
    """
    if locator is not None:
        if by is not None or value is not None:
            raise ValueError("Cannot use both 'locator' and 'by/value' arguments")
        by, value = locator

    if (by is not None) != (value is not None):
        raise ValueError("Must provide both 'by' and 'value', or neither")

    if by is not None and value is not None:
        from selenium_expect._locator import LocatorExpect

        if not isinstance(target, WebDriver):
            raise TypeError("expect() with by/value requires a WebDriver target")

        effective_config = config if config is not None else get_config()
        if timeout is not None or polling is not None or soft is not None:
            overrides: dict[str, Any] = {}
            if timeout is not None:
                overrides["timeout"] = normalize_timeout(timeout)
            if polling is not None:
                if isinstance(polling, list):
                    overrides["polling_intervals"] = polling
                else:
                    overrides["polling_interval"] = polling
            if soft is not None:
                overrides["soft_mode"] = soft
            effective_config = effective_config.replace(**overrides)

        return LocatorExpect(
            driver=target,
            by=by,
            value=value,
            config=effective_config,
            message=message,
        )

    if target is None:
        raise TypeError("expect() does not support None as target")

    type_name = _resolve_target_type(target)
    cls = ASSERTION_REGISTRY.get(type_name)
    if cls is None:
        raise TypeError(f"expect() does not support target type '{type_name}'")

    assertion_cls = cast(type[AssertionMixin], cls)

    effective_config = config if config is not None else get_config()

    if timeout is not None or polling is not None or soft is not None:
        cfg_overrides: dict[str, Any] = {}
        if timeout is not None:
            cfg_overrides["timeout"] = normalize_timeout(timeout)
        if polling is not None:
            if isinstance(polling, list):
                cfg_overrides["polling_intervals"] = polling
            else:
                cfg_overrides["polling_interval"] = polling
        if soft is not None:
            cfg_overrides["soft_mode"] = soft
        effective_config = effective_config.replace(**cfg_overrides)

    return assertion_cls(target=target, config=effective_config, message=message)

configure

configure(**defaults: Any) -> Callable[..., AssertionMixin]

Create a pre-configured expect variant.

Returns a callable that behaves like expect() with defaults pre-applied. Explicit kwargs from the caller override the defaults.

Usage::

fast_expect = expect.configure(timeout=1.0, polling=0.1)
fast_expect(el).to_be_visible()
Source code in selenium_expect/_expect.py
def configure(self, **defaults: Any) -> Callable[..., AssertionMixin]:
    """Create a pre-configured expect variant.

    Returns a callable that behaves like ``expect()`` with *defaults*
    pre-applied. Explicit kwargs from the caller override the defaults.

    Usage::

        fast_expect = expect.configure(timeout=1.0, polling=0.1)
        fast_expect(el).to_be_visible()
    """

    def _configured_expect(
        target: Any,
        /,
        **overrides: Any,
    ) -> AssertionMixin:
        merged: dict[str, Any] = {**defaults, **overrides}
        return self(target, **merged)

    return _configured_expect

poll

poll(fn: Callable[[], Any], *, timeout: float | None = None, polling: float | list[float] | None = None, config: ExpectConfig | None = None) -> PollAssertion

Create a PollAssertion for retry-based assertions on fn.

Usage::

expect.poll(lambda: driver.execute_script("return document.readyState"))
    .to_equal("complete")
Source code in selenium_expect/_expect.py
def poll(
    self,
    fn: Callable[[], Any],
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
    config: ExpectConfig | None = None,
) -> PollAssertion:
    """Create a ``PollAssertion`` for retry-based assertions on *fn*.

    Usage::

        expect.poll(lambda: driver.execute_script("return document.readyState"))
            .to_equal("complete")
    """
    return PollAssertion(fn, timeout=timeout, polling=polling, config=config)

ExpectConfig

Immutable configuration dataclass for all assertions.

Fields

Field Type Default Description
timeout float 5.0 Default timeout in seconds
polling_interval float 0.5 Fixed polling interval
polling_intervals list[float] \| None None Backoff schedule
screenshot_on_failure bool False Capture screenshot on failure
screenshot_path str \| None None Screenshot directory
debug_mode bool False Debug logging
soft_mode bool False Soft assertion mode

Usage

from selenium_expect import ExpectConfig, expect

# Create a custom config
config = ExpectConfig(timeout=10, polling_interval=0.25, debug_mode=True)

# Use with expect.configure()
debug_expect = expect.configure(timeout=10, polling=0.25, debug_mode=True)

selenium_expect._config.ExpectConfig dataclass

Immutable configuration for expect assertions.

Use replace() to create a new instance with overridden fields. The global config singleton is mutated via the module-level setters.

Source code in selenium_expect/_config.py
@dataclass(frozen=True, slots=True)
class ExpectConfig:
    """Immutable configuration for expect assertions.

    Use ``replace()`` to create a new instance with overridden fields.
    The global config singleton is mutated via the module-level setters.
    """

    timeout: float = 5.0
    polling_interval: float = 0.5
    polling_intervals: list[float] | None = None
    screenshot_on_failure: bool = False
    screenshot_path: str | None = None
    debug_mode: bool = False
    soft_mode: bool = False

    def __post_init__(self) -> None:
        if self.timeout < 0:
            raise ValueError(f"timeout must be >= 0, got {self.timeout}")
        if self.polling_interval < 0:
            raise ValueError(f"polling_interval must be >= 0, got {self.polling_interval}")
        if self.polling_intervals is not None:
            if len(self.polling_intervals) == 0:
                raise ValueError("polling_intervals must not be empty; use None for fixed interval")
            for i, interval in enumerate(self.polling_intervals):
                if interval < 0:
                    raise ValueError(f"polling_intervals[{i}] must be >= 0, got {interval}")

    def replace(self, **kwargs: Any) -> ExpectConfig:
        """Return a new instance with overridden fields."""
        return _replace(self, **kwargs)

replace

replace(**kwargs: Any) -> ExpectConfig

Return a new instance with overridden fields.

Source code in selenium_expect/_config.py
def replace(self, **kwargs: Any) -> ExpectConfig:
    """Return a new instance with overridden fields."""
    return _replace(self, **kwargs)

poll(fn, ...)

Create a PollAssertion for retry-based assertions on an arbitrary function.

Parameters

Parameter Type Default Description
fn Callable[[], Any] Zero-argument callable to poll
timeout float None Override default timeout
polling float \| list[float] None Override default polling

Example

from selenium_expect import expect, poll

# Using expect.poll
expect.poll(lambda: driver.execute_script("return document.readyState")).to_equal("complete")

# Using standalone poll
poll(lambda: driver.current_url, timeout=10).to_match(r"https://.*\.example\.com")

selenium_expect._poll.poll

poll(fn: Callable[[], Any], *, timeout: float | None = None, polling: float | list[float] | None = None, config: ExpectConfig | None = None) -> PollAssertion

Create a PollAssertion for retry-based assertions on fn.

Usage::

poll(lambda: driver.execute_script("return document.readyState"))
    .to_equal("complete")
Source code in selenium_expect/_poll.py
def poll(
    fn: Callable[[], Any],
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
    config: ExpectConfig | None = None,
) -> PollAssertion:
    """Create a ``PollAssertion`` for retry-based assertions on *fn*.

    Usage::

        poll(lambda: driver.execute_script("return document.readyState"))
            .to_equal("complete")
    """
    return PollAssertion(fn, timeout=timeout, polling=polling, config=config)

PollAssertion

Assertion over an arbitrary function with retry loop.

Methods

Method Description
to_equal(expected) Assert fn() == expected
to_be_truthy() Assert bool(fn()) is True
to_be_falsy() Assert bool(fn()) is False
to_be_none() Assert fn() is None
to_contain(expected) Assert expected in fn()
to_match(pattern) Assert re.search(pattern, str(fn())) matches
to_be_greater_than(expected) Assert fn() > expected
to_be_less_than(expected) Assert fn() < expected
to_be_in_list(expected) Assert fn() in expected
to_have_length(expected) Assert len(fn()) == expected

selenium_expect._poll.PollAssertion

Assertion over an arbitrary function with retry loop.

Source code in selenium_expect/_poll.py
class PollAssertion:
    """Assertion over an arbitrary function with retry loop."""

    def __init__(
        self,
        fn: Callable[[], Any],
        timeout: float | None = None,
        polling: float | list[float] | None = None,
        config: ExpectConfig | None = None,
    ) -> None:
        self._fn = fn
        self._config = config if config is not None else get_config()
        self._timeout = _normalize_timeout(timeout) if timeout is not None else self._config.timeout
        if self._timeout < 0:
            raise ValueError(f"timeout must be >= 0, got {self._timeout}")
        if polling is None:
            self._polling_interval = self._config.polling_interval
            self._polling_intervals = self._config.polling_intervals
        elif isinstance(polling, list):
            if len(polling) == 0:
                raise ValueError("polling list must not be empty; use a float for fixed interval")
            self._polling_interval = 0.5
            self._polling_intervals = polling
        else:
            self._polling_interval = polling
            self._polling_intervals = None
        if self._polling_interval < 0:
            raise ValueError(f"polling interval must be >= 0, got {self._polling_interval}")
        if self._polling_intervals is not None:
            for i, interval in enumerate(self._polling_intervals):
                if interval < 0:
                    raise ValueError(f"polling_intervals[{i}] must be >= 0, got {interval}")

    def _run(
        self,
        condition: Callable[[], tuple[bool, Any]],
        condition_name: str,
        expected: Any = None,
    ) -> None:
        """Execute the retry loop and raise on failure."""
        result = retry_until(
            condition=condition,
            timeout=self._timeout,
            polling_interval=self._polling_interval,
            polling_intervals=self._polling_intervals,
            debug=self._config.debug_mode,
        )
        if result.passed:
            return
        error_msg = AssertionFormatter.format_error(
            entity="poll()",
            condition=condition_name,
            expected=expected,
            actual=result.actual_value,
            elapsed_ms=result.elapsed_ms,
            poll_count=result.poll_count,
            polling_interval=self._polling_interval,
            timeline=result.timeline,
        )
        if self._config.soft_mode:
            from selenium_expect._soft import SoftAssertionCollector

            SoftAssertionCollector.add_failure(error_msg)
        else:
            raise AssertionError(error_msg)

    def to_equal(self, expected: Any) -> None:
        """Assert fn() == expected."""
        fn = self._fn

        def condition() -> tuple[bool, Any]:
            actual = fn()
            return (actual == expected, actual)

        self._run(condition, f"to equal {expected!r}", expected)

    def to_be_truthy(self) -> None:
        """Assert bool(fn()) is True."""
        fn = self._fn

        def condition() -> tuple[bool, Any]:
            actual = fn()
            return (bool(actual), actual)

        self._run(condition, "to be truthy", True)

    def to_be_falsy(self) -> None:
        """Assert bool(fn()) is False."""
        fn = self._fn

        def condition() -> tuple[bool, Any]:
            actual = fn()
            return (not bool(actual), actual)

        self._run(condition, "to be falsy", False)

    def to_be_none(self) -> None:
        """Assert fn() is None."""
        fn = self._fn

        def condition() -> tuple[bool, Any]:
            actual = fn()
            return (actual is None, actual)

        self._run(condition, "to be None", None)

    def to_contain(self, expected: Any) -> None:
        """Assert expected in fn()."""
        fn = self._fn

        def condition() -> tuple[bool, Any]:
            actual = fn()
            if actual is None:
                return (False, actual)
            try:
                return (expected in actual, actual)
            except TypeError:
                return (False, f"not iterable: {actual!r}")

        self._run(condition, f"to contain {expected!r}", expected)

    def to_match(self, pattern: str) -> None:
        """Assert re.search(pattern, str(fn()))."""
        fn = self._fn

        def condition() -> tuple[bool, Any]:
            actual = fn()
            return (re.search(pattern, str(actual)) is not None, actual)

        self._run(condition, f"to match {pattern!r}", pattern)

    def to_be_greater_than(self, expected: Any) -> None:
        """Assert fn() > expected."""
        fn = self._fn

        def condition() -> tuple[bool, Any]:
            actual = fn()
            try:
                return (actual > expected, actual)
            except TypeError:
                return (False, f"not comparable: {actual!r} > {expected!r}")

        self._run(condition, f"to be greater than {expected}", expected)

    def to_be_less_than(self, expected: Any) -> None:
        """Assert fn() < expected."""
        fn = self._fn

        def condition() -> tuple[bool, Any]:
            actual = fn()
            try:
                return (actual < expected, actual)
            except TypeError:
                return (False, f"not comparable: {actual!r} < {expected!r}")

        self._run(condition, f"to be less than {expected}", expected)

    def to_be_in_list(self, expected: list[Any]) -> None:
        """Assert fn() in expected."""
        fn = self._fn

        def condition() -> tuple[bool, Any]:
            actual = fn()
            return (actual in expected, actual)

        self._run(condition, f"to be in {expected!r}", expected)

    def to_have_length(self, expected: int) -> None:
        """Assert len(fn()) == expected."""
        fn = self._fn

        def condition() -> tuple[bool, Any]:
            actual = fn()
            try:
                actual_len = len(actual)
            except TypeError:
                return (False, f"no len() for {actual!r}")
            return (actual_len == expected, actual_len)

        self._run(condition, f"to have length {expected}", expected)

to_be_falsy

to_be_falsy() -> None

Assert bool(fn()) is False.

Source code in selenium_expect/_poll.py
def to_be_falsy(self) -> None:
    """Assert bool(fn()) is False."""
    fn = self._fn

    def condition() -> tuple[bool, Any]:
        actual = fn()
        return (not bool(actual), actual)

    self._run(condition, "to be falsy", False)

to_be_greater_than

to_be_greater_than(expected: Any) -> None

Assert fn() > expected.

Source code in selenium_expect/_poll.py
def to_be_greater_than(self, expected: Any) -> None:
    """Assert fn() > expected."""
    fn = self._fn

    def condition() -> tuple[bool, Any]:
        actual = fn()
        try:
            return (actual > expected, actual)
        except TypeError:
            return (False, f"not comparable: {actual!r} > {expected!r}")

    self._run(condition, f"to be greater than {expected}", expected)

to_be_in_list

to_be_in_list(expected: list[Any]) -> None

Assert fn() in expected.

Source code in selenium_expect/_poll.py
def to_be_in_list(self, expected: list[Any]) -> None:
    """Assert fn() in expected."""
    fn = self._fn

    def condition() -> tuple[bool, Any]:
        actual = fn()
        return (actual in expected, actual)

    self._run(condition, f"to be in {expected!r}", expected)

to_be_less_than

to_be_less_than(expected: Any) -> None

Assert fn() < expected.

Source code in selenium_expect/_poll.py
def to_be_less_than(self, expected: Any) -> None:
    """Assert fn() < expected."""
    fn = self._fn

    def condition() -> tuple[bool, Any]:
        actual = fn()
        try:
            return (actual < expected, actual)
        except TypeError:
            return (False, f"not comparable: {actual!r} < {expected!r}")

    self._run(condition, f"to be less than {expected}", expected)

to_be_none

to_be_none() -> None

Assert fn() is None.

Source code in selenium_expect/_poll.py
def to_be_none(self) -> None:
    """Assert fn() is None."""
    fn = self._fn

    def condition() -> tuple[bool, Any]:
        actual = fn()
        return (actual is None, actual)

    self._run(condition, "to be None", None)

to_be_truthy

to_be_truthy() -> None

Assert bool(fn()) is True.

Source code in selenium_expect/_poll.py
def to_be_truthy(self) -> None:
    """Assert bool(fn()) is True."""
    fn = self._fn

    def condition() -> tuple[bool, Any]:
        actual = fn()
        return (bool(actual), actual)

    self._run(condition, "to be truthy", True)

to_contain

to_contain(expected: Any) -> None

Assert expected in fn().

Source code in selenium_expect/_poll.py
def to_contain(self, expected: Any) -> None:
    """Assert expected in fn()."""
    fn = self._fn

    def condition() -> tuple[bool, Any]:
        actual = fn()
        if actual is None:
            return (False, actual)
        try:
            return (expected in actual, actual)
        except TypeError:
            return (False, f"not iterable: {actual!r}")

    self._run(condition, f"to contain {expected!r}", expected)

to_equal

to_equal(expected: Any) -> None

Assert fn() == expected.

Source code in selenium_expect/_poll.py
def to_equal(self, expected: Any) -> None:
    """Assert fn() == expected."""
    fn = self._fn

    def condition() -> tuple[bool, Any]:
        actual = fn()
        return (actual == expected, actual)

    self._run(condition, f"to equal {expected!r}", expected)

to_have_length

to_have_length(expected: int) -> None

Assert len(fn()) == expected.

Source code in selenium_expect/_poll.py
def to_have_length(self, expected: int) -> None:
    """Assert len(fn()) == expected."""
    fn = self._fn

    def condition() -> tuple[bool, Any]:
        actual = fn()
        try:
            actual_len = len(actual)
        except TypeError:
            return (False, f"no len() for {actual!r}")
        return (actual_len == expected, actual_len)

    self._run(condition, f"to have length {expected}", expected)

to_match

to_match(pattern: str) -> None

Assert re.search(pattern, str(fn())).

Source code in selenium_expect/_poll.py
def to_match(self, pattern: str) -> None:
    """Assert re.search(pattern, str(fn()))."""
    fn = self._fn

    def condition() -> tuple[bool, Any]:
        actual = fn()
        return (re.search(pattern, str(actual)) is not None, actual)

    self._run(condition, f"to match {pattern!r}", pattern)

extend(name)

Decorator to register a custom matcher under name.

Parameters

Parameter Type Description
name str Method name to register (e.g. "to_be_in_viewport")

Matcher signature

def my_matcher(target: Any, *args, **kwargs) -> tuple[bool, Any]:
    ...
    return (passed, actual_value)

Example

from selenium_expect import extend

@extend("to_have_trimmed_text")
def check_trimmed_text(element, expected: str):
    actual = element.text.strip()
    return (actual == expected, actual)

# Usage
expect(element).to_have_trimmed_text("Hello!")
expect(element).not_.to_have_trimmed_text("  Hello!  ")

selenium_expect._matcher.extend

extend(name: str) -> Callable[[_MatcherFn], _MatcherFn]

Decorator to register a custom matcher under name.

Usage::

@extend("to_be_in_viewport")
def check_in_viewport(element: Any) -> tuple[bool, Any]:
    ...
    return (passed, actual_value)

The matcher function receives the assertion's _target as its first argument and must return a (bool, Any) tuple where the bool indicates pass/fail and the Any is the actual value for error reporting.

Source code in selenium_expect/_matcher.py
def extend(name: str) -> Callable[[_MatcherFn], _MatcherFn]:
    """Decorator to register a custom matcher under *name*.

    Usage::

        @extend("to_be_in_viewport")
        def check_in_viewport(element: Any) -> tuple[bool, Any]:
            ...
            return (passed, actual_value)

    The matcher function receives the assertion's ``_target`` as its
    first argument and must return a ``(bool, Any)`` tuple where the
    bool indicates pass/fail and the Any is the actual value for
    error reporting.
    """

    def decorator(fn: Callable[..., tuple[bool, Any]]) -> Callable[..., tuple[bool, Any]]:
        CustomMatcherRegistry.register(name, fn)
        fn._selenium_expect_matcher = name  # type: ignore[attr-defined]
        return fn

    return decorator

merge_expects(*modules)

Combine custom matchers from multiple modules into the registry.

Parameters

Parameter Type Description
*modules ModuleType \| str Modules or importable module paths

Example

from selenium_expect import merge_expects

# Pass module objects
import my_project.matchers
import my_project.custom_assertions
merge_expects(my_project.matchers, my_project.custom_assertions)

# Or pass importable strings
merge_expects("my_project.matchers", "my_project.custom_assertions")

selenium_expect._matcher.merge_expects

merge_expects(*modules: ModuleType | str) -> list[str]

Combine custom matchers from multiple modules into the registry.

Each module should have used @extend to register matchers. Pass modules as objects or importable strings.

Usage::

import my_matchers
merge_expects(my_matchers)

# or by import path:
merge_expects("my_project.matchers")

Returns the list of newly registered matcher names.

Source code in selenium_expect/_matcher.py
def merge_expects(*modules: ModuleType | str) -> list[str]:
    """Combine custom matchers from multiple modules into the registry.

    Each module should have used ``@extend`` to register matchers.
    Pass modules as objects or importable strings.

    Usage::

        import my_matchers
        merge_expects(my_matchers)

        # or by import path:
        merge_expects("my_project.matchers")

    Returns the list of newly registered matcher names.
    """
    import importlib

    resolved: list[ModuleType] = []
    for mod in modules:
        if isinstance(mod, str):
            resolved.append(importlib.import_module(mod))
        else:
            resolved.append(mod)
    return CustomMatcherRegistry.merge_from(*resolved)

SoftAssertionCollector

Collects soft assertion failures for deferred raising.

Methods

Method Description
reset() Clear all collected failures
get_failures() Return list of failure messages
assert_all() Raise AssertionError if any failures, then reset

Example

from selenium_expect import expect, SoftAssertionCollector, assert_all

SoftAssertionCollector.reset()

expect(element).to_be_visible(soft=True)
expect(element).to_have_text("Hello", soft=True)

failures = SoftAssertionCollector.get_failures()
if failures:
    print(f"{len(failures)} failures collected")

assert_all()  # raises if any failures

selenium_expect._soft.SoftAssertionCollector

Collects soft assertion failures for deferred raising.

Source code in selenium_expect/_soft.py
class SoftAssertionCollector:
    """Collects soft assertion failures for deferred raising."""

    _failures: ClassVar[list[str]] = []

    @classmethod
    def add_failure(cls, message: str) -> None:
        """Record a soft assertion failure."""
        cls._failures.append(message)

    @classmethod
    def get_failures(cls) -> list[str]:
        """Return all collected failures."""
        return list(cls._failures)

    @classmethod
    def reset(cls) -> None:
        """Clear all collected failures."""
        cls._failures.clear()

    @classmethod
    def assert_all(cls) -> None:
        """Raise ``AssertionError`` if any failures were collected, then reset."""
        if not cls._failures:
            return
        messages = list(cls._failures)
        cls.reset()
        combined = "\n---\n".join(messages)
        raise AssertionError(f"Soft assertion failures ({len(messages)}):\n{combined}")

add_failure classmethod

add_failure(message: str) -> None

Record a soft assertion failure.

Source code in selenium_expect/_soft.py
@classmethod
def add_failure(cls, message: str) -> None:
    """Record a soft assertion failure."""
    cls._failures.append(message)

assert_all classmethod

assert_all() -> None

Raise AssertionError if any failures were collected, then reset.

Source code in selenium_expect/_soft.py
@classmethod
def assert_all(cls) -> None:
    """Raise ``AssertionError`` if any failures were collected, then reset."""
    if not cls._failures:
        return
    messages = list(cls._failures)
    cls.reset()
    combined = "\n---\n".join(messages)
    raise AssertionError(f"Soft assertion failures ({len(messages)}):\n{combined}")

get_failures classmethod

get_failures() -> list[str]

Return all collected failures.

Source code in selenium_expect/_soft.py
@classmethod
def get_failures(cls) -> list[str]:
    """Return all collected failures."""
    return list(cls._failures)

reset classmethod

reset() -> None

Clear all collected failures.

Source code in selenium_expect/_soft.py
@classmethod
def reset(cls) -> None:
    """Clear all collected failures."""
    cls._failures.clear()

assert_all()

Raise AssertionError if any soft failures were collected, then reset.

Example

from selenium_expect import expect, assert_all

expect(element).to_be_visible(soft=True)
expect(element).to_have_text("Hello", soft=True)

assert_all()  # raises AssertionError with combined message if any failed

selenium_expect._soft.assert_all

assert_all() -> None

Raise AssertionError if any soft failures were collected, then reset.

Convenience wrapper around SoftAssertionCollector.assert_all().

Source code in selenium_expect/_soft.py
def assert_all() -> None:
    """Raise ``AssertionError`` if any soft failures were collected, then reset.

    Convenience wrapper around ``SoftAssertionCollector.assert_all()``.
    """
    SoftAssertionCollector.assert_all()

Configuration setters

set_default_timeout(seconds)

Set the global default timeout for all assertions.

from selenium_expect import set_default_timeout

set_default_timeout(10)     # 10 seconds
set_default_timeout(5000)   # interpreted as 5000ms = 5 seconds (int >= 1000)

selenium_expect._config.set_default_timeout

set_default_timeout(seconds: float) -> None

Set the default timeout for all expect assertions.

If seconds is an int >= 1000, it is interpreted as milliseconds (consistent with expect(timeout=...)).

Source code in selenium_expect/_config.py
def set_default_timeout(seconds: float) -> None:
    """Set the default timeout for all expect assertions.

    If *seconds* is an int >= 1000, it is interpreted as milliseconds
    (consistent with ``expect(timeout=...)``).
    """
    global _global_config
    _global_config = _global_config.replace(timeout=normalize_timeout(seconds))

set_default_polling_interval(seconds)

Set the global default polling interval (fixed).

from selenium_expect import set_default_polling_interval

set_default_polling_interval(0.25)

selenium_expect._config.set_default_polling_interval

set_default_polling_interval(seconds: float) -> None

Set the default polling interval for all expect assertions.

Source code in selenium_expect/_config.py
def set_default_polling_interval(seconds: float) -> None:
    """Set the default polling interval for all expect assertions."""
    global _global_config
    _global_config = _global_config.replace(polling_interval=seconds)

set_default_polling_intervals(intervals)

Set a backoff schedule for polling. The list is cycled through during the retry loop.

from selenium_expect import set_default_polling_intervals

set_default_polling_intervals([0.1, 0.2, 0.5, 1.0])

selenium_expect._config.set_default_polling_intervals

set_default_polling_intervals(intervals: list[float]) -> None

Set a backoff schedule for polling intervals.

Source code in selenium_expect/_config.py
def set_default_polling_intervals(intervals: list[float]) -> None:
    """Set a backoff schedule for polling intervals."""
    global _global_config
    _global_config = _global_config.replace(polling_intervals=intervals)

set_screenshot_on_failure(enabled, path=None)

Enable automatic screenshot capture on assertion failure.

from selenium_expect import set_screenshot_on_failure

set_screenshot_on_failure(True, path="./screenshots/")

selenium_expect._config.set_screenshot_on_failure

set_screenshot_on_failure(enabled: bool, path: str | None = None) -> None

Enable or disable screenshot capture on assertion failure.

Source code in selenium_expect/_config.py
def set_screenshot_on_failure(enabled: bool, path: str | None = None) -> None:
    """Enable or disable screenshot capture on assertion failure."""
    global _global_config
    _global_config = _global_config.replace(
        screenshot_on_failure=enabled,
        screenshot_path=path if path is not None else "./screenshots/",
    )

set_debug_mode(enabled)

Enable debug logging for retry loops. Prints poll count, elapsed time, and actual values.

from selenium_expect import set_debug_mode

set_debug_mode(True)

selenium_expect._config.set_debug_mode

set_debug_mode(enabled: bool) -> None

Enable or disable debug logging for retry loops.

Source code in selenium_expect/_config.py
def set_debug_mode(enabled: bool) -> None:
    """Enable or disable debug logging for retry loops."""
    global _global_config
    _global_config = _global_config.replace(debug_mode=enabled)

get_config()

Return the current global ExpectConfig instance.

from selenium_expect import get_config

config = get_config()
print(f"Timeout: {config.timeout}s, Polling: {config.polling_interval}s")

selenium_expect._config.get_config

get_config() -> ExpectConfig

Return the current global config.

Source code in selenium_expect/_config.py
def get_config() -> ExpectConfig:
    """Return the current global config."""
    return _global_config

Assertion classes

ExpectElement

Assertions for WebElement objects. Provides methods for visibility, state, text, attributes, CSS, identity, position, accessibility, shadow DOM, and JavaScript properties.

Key method categories:

  • State: to_be_visible, to_be_hidden, to_be_present, to_be_enabled, to_be_disabled, to_be_selected, to_be_checked, to_be_clickable, to_be_stale
  • Text: to_have_text, to_have_text_contains, to_have_text_matches, to_have_trimmed_text
  • Attributes: to_have_attribute, to_have_attribute_present, to_have_attribute_absent, to_have_class, to_have_class_contain, to_have_id, to_have_value
  • CSS: to_have_css_property, to_have_css_value_contains
  • Identity: to_have_tag, to_have_role, to_have_aria_label, to_have_aria_describedby
  • Position: to_have_position, to_have_size, to_have_rect
  • Composition: to_satisfy_all, to_satisfy_any, to_satisfy_none

selenium_expect.assertions.element.ExpectElement

Bases: AssertionMixin

Assertions for WebElement state, text, attributes, CSS, identity, position.

Source code in selenium_expect/assertions/element.py
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
class ExpectElement(AssertionMixin):
    """Assertions for WebElement state, text, attributes, CSS, identity, position."""

    def __init__(
        self,
        target: WebElement,
        config: ExpectConfig | None = None,
        message: str | None = None,
        negate: bool = False,
    ) -> None:
        super().__init__(target=target, config=config, message=message, negate=negate)

    # --- State ---

    def to_be_visible(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.is_displayed() == True."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            return (el.is_displayed(), el.is_displayed())

        self._run_assertion(
            condition=condition,
            condition_name="to be visible",
            expected=True,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_hidden(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.is_displayed() == False."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            displayed = el.is_displayed()
            return (not displayed, displayed)

        self._run_assertion(
            condition=condition,
            condition_name="to be hidden",
            expected=False,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_enabled(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.is_enabled() == True."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            return (el.is_enabled(), el.is_enabled())

        self._run_assertion(
            condition=condition,
            condition_name="to be enabled",
            expected=True,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_disabled(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.is_enabled() == False."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            enabled = el.is_enabled()
            return (not enabled, enabled)

        self._run_assertion(
            condition=condition,
            condition_name="to be disabled",
            expected=False,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_checked(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.is_selected() == True (checkbox/radio)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            return (el.is_selected(), el.is_selected())

        self._run_assertion(
            condition=condition,
            condition_name="to be checked",
            expected=True,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_selected(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.is_selected() == True (option/checkbox/radio)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            return (el.is_selected(), el.is_selected())

        self._run_assertion(
            condition=condition,
            condition_name="to be selected",
            expected=True,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_present(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element exists in DOM (element.tag_name doesn't raise)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            try:
                tag = el.tag_name
                return (True, tag)
            except Exception as exc:
                return (False, str(exc))

        self._run_assertion(
            condition=condition,
            condition_name="to be present",
            expected=True,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_absent(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element doesn't exist (raises StaleElementReferenceException
        or NoSuchElementException)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            try:
                el.tag_name  # noqa: B018
                return (False, "present")
            except Exception:
                return (True, "absent")

        self._run_assertion(
            condition=condition,
            condition_name="to be absent",
            expected=True,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_clickable(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.is_displayed() and element.is_enabled()."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            displayed = el.is_displayed()
            enabled = el.is_enabled()
            clickable = displayed and enabled
            return (clickable, {"displayed": displayed, "enabled": enabled})

        self._run_assertion(
            condition=condition,
            condition_name="to be clickable",
            expected=True,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_stale(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element is stale (any access raises StaleElementReferenceException)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            try:
                el.tag_name  # noqa: B018
                return (False, "not stale")
            except Exception:
                return (True, "stale")

        self._run_assertion(
            condition=condition,
            condition_name="to be stale",
            expected=True,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_unselected(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.is_selected() == False (semantic alias for not_.to_be_selected())."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            selected = el.is_selected()
            return (not selected, selected)

        self._run_assertion(
            condition=condition,
            condition_name="to be unselected",
            expected=False,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_unchecked(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.is_selected() == False (semantic alias for not_.to_be_checked())."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            selected = el.is_selected()
            return (not selected, selected)

        self._run_assertion(
            condition=condition,
            condition_name="to be unchecked",
            expected=False,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_focused(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element is the active element (driver.switch_to.active_element == element)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            driver = getattr(el, "parent", None)
            if driver is None:
                return (False, "no driver")
            active = driver.switch_to.active_element
            return (active.id == el.id, active)

        self._run_assertion(
            condition=condition,
            condition_name="to be focused",
            expected=True,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_editable(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element is editable (input/textarea, not readonly, not disabled)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            tag = el.tag_name
            if tag not in ("input", "textarea"):
                return (False, f"tag={tag!r}")
            if not el.is_enabled():
                return (False, "disabled")
            readonly = el.get_attribute("readonly")
            if readonly is not None:
                return (False, "readonly")
            return (True, "editable")

        self._run_assertion(
            condition=condition,
            condition_name="to be editable",
            expected=True,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_readonly(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element is readonly (get_attribute('readonly') is not None)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute("readonly")
            return (actual is not None, actual)

        self._run_assertion(
            condition=condition,
            condition_name="to be readonly",
            expected="not None",
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_be_empty(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.text.strip() == '' (no visible text)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.text
            return ((actual or "").strip() == "", actual)

        self._run_assertion(
            condition=condition,
            condition_name="to be empty",
            expected="",
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    # --- Text ---

    def to_have_text(
        self,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.text == text."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.text
            return (actual == text, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have text {text!r}",
            expected=text,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_text_contains(
        self,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert text in element.text."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.text
            return (text in (actual or ""), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have text containing {text!r}",
            expected=text,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_text_matches(
        self,
        pattern: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert re.search(pattern, element.text)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.text
            return (re.search(pattern, actual or "") is not None, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have text matching {pattern!r}",
            expected=pattern,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_text_empty(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.text == ''."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.text
            return (actual == "", actual)

        self._run_assertion(
            condition=condition,
            condition_name="to have text empty",
            expected="",
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_text_not_empty(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.text != ''."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.text
            return (bool(actual), actual)

        self._run_assertion(
            condition=condition,
            condition_name="to have text not empty",
            expected="non-empty",
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_text_starting_with(
        self,
        prefix: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.text.startswith(prefix)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.text
            return ((actual or "").startswith(prefix), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have text starting with {prefix!r}",
            expected=prefix,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_text_ending_with(
        self,
        suffix: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.text.endswith(suffix)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.text
            return ((actual or "").endswith(suffix), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have text ending with {suffix!r}",
            expected=suffix,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_text_in_list(
        self,
        *texts: str,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.text is one of *texts."""
        if not texts:
            raise ValueError("At least one text must be provided")
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.text
            return (actual in texts, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have text in {list(texts)!r}",
            expected=list(texts),
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_value(
        self,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.get_attribute('value') == value."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute("value")
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have value {value!r}",
            expected=value,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_value_contains(
        self,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert value in element.get_attribute('value')."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute("value")
            return (value in (actual or ""), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have value containing {value!r}",
            expected=value,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_value_matches(
        self,
        pattern: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert re.search(pattern, element.get_attribute('value'))."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute("value")
            return (re.search(pattern, actual or "") is not None, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have value matching {pattern!r}",
            expected=pattern,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_value_in_list(
        self,
        values: list[str],
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.get_attribute('value') in values."""
        if not values:
            raise ValueError("values list must not be empty")
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute("value")
            return (actual in values, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have value in {values!r}",
            expected=values,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    # --- Attributes ---

    def to_have_attribute(
        self,
        name: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.get_attribute(name) == value."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute(name)
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have attribute {name!r}={value!r}",
            expected=value,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_attribute_contains(
        self,
        name: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert value in element.get_attribute(name)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute(name)
            return (value in (actual or ""), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have attribute {name!r} containing {value!r}",
            expected=value,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_attribute_matches(
        self,
        name: str,
        pattern: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert re.search(pattern, element.get_attribute(name))."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute(name)
            return (re.search(pattern, actual or "") is not None, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have attribute {name!r} matching {pattern!r}",
            expected=pattern,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_attribute_empty(
        self,
        name: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.get_attribute(name) == '' or None."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute(name)
            return (actual is None or actual == "", actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have attribute {name!r} empty",
            expected="empty or None",
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_attribute_present(
        self,
        name: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.get_attribute(name) is not None."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute(name)
            return (actual is not None, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have attribute {name!r} present",
            expected="present",
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_attribute_absent(
        self,
        name: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.get_attribute(name) is None."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute(name)
            return (actual is None, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have attribute {name!r} absent",
            expected="absent",
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_attribute_in_list(
        self,
        name: str,
        values: list[str],
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.get_attribute(name) in values."""
        if not values:
            raise ValueError("values list must not be empty")
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute(name)
            return (actual in values, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have attribute {name!r} in {values!r}",
            expected=values,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_dom_attribute(
        self,
        name: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.get_dom_attribute(name) == value."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_dom_attribute(name)
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have DOM attribute {name!r}={value!r}",
            expected=value,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_dom_attribute_contains(
        self,
        name: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert value in element.get_dom_attribute(name)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_dom_attribute(name)
            return (value in (actual or ""), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have DOM attribute {name!r} containing {value!r}",
            expected=value,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_property(
        self,
        name: str,
        value: Any,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.get_property(name) == value."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_property(name)
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have property {name!r}={value!r}",
            expected=value,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_property_contains(
        self,
        name: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert value in str(element.get_property(name))."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_property(name)
            if actual is None:
                return (False, actual)
            return (value in str(actual), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have property {name!r} containing {value!r}",
            expected=value,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    # --- CSS properties ---

    def to_have_css_property(
        self,
        name: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.value_of_css_property(name) == value."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.value_of_css_property(name)
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have CSS {name!r}={value!r}",
            expected=value,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_css_property_contains(
        self,
        name: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert value in element.value_of_css_property(name)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.value_of_css_property(name)
            return (value in (actual or ""), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have CSS {name!r} containing {value!r}",
            expected=value,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_css_property_matches(
        self,
        name: str,
        pattern: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert re.search(pattern, element.value_of_css_property(name))."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.value_of_css_property(name)
            return (re.search(pattern, actual or "") is not None, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have CSS {name!r} matching {pattern!r}",
            expected=pattern,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    # --- Identity / DOM ---

    def to_have_tag(
        self,
        tag: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.tag_name == tag."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.tag_name
            return (actual == tag, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have tag {tag!r}",
            expected=tag,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_id(
        self,
        id: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.get_attribute('id') == id."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute("id")
            return (actual == id, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have id {id!r}",
            expected=id,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_class(
        self,
        class_name: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert class_name in element.get_attribute('class').split()."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute("class")
            classes = (actual or "").split()
            return (class_name in classes, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have class {class_name!r}",
            expected=class_name,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_class_contains(
        self,
        class_name: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert class_name in element.get_attribute('class') (substring)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute("class")
            return (class_name in (actual or ""), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have class containing {class_name!r}",
            expected=class_name,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_contain_class(
        self,
        class_name: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert class_name in element.get_attribute('class').split() (alias of to_have_class)."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute("class")
            classes = (actual or "").split()
            return (class_name in classes, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to contain class {class_name!r}",
            expected=class_name,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_class_matching(
        self,
        pattern: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert any class in element.get_attribute('class').split() matches pattern."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute("class")
            classes = (actual or "").split()
            return (any(re.search(pattern, c) for c in classes), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have class matching {pattern!r}",
            expected=pattern,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_all_classes(
        self,
        *classes: str,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element has all specified classes."""
        if not classes:
            raise ValueError("At least one class must be provided")
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute("class")
            elem_classes = set((actual or "").split())
            return (set(classes).issubset(elem_classes), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have all classes {list(classes)!r}",
            expected=list(classes),
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_class_in_list(
        self,
        *classes: str,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element has at least one of the specified classes."""
        if not classes:
            raise ValueError("At least one class must be provided")
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.get_attribute("class")
            elem_classes = set((actual or "").split())
            return (bool(elem_classes & set(classes)), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have class in {list(classes)!r}",
            expected=list(classes),
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    # --- Position / dimensions ---

    def to_have_location(
        self,
        x: int,
        y: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.location == {'x': x, 'y': y}."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            loc = el.location
            actual = {"x": loc["x"], "y": loc["y"]}
            return (actual == {"x": x, "y": y}, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have location ({x}, {y})",
            expected={"x": x, "y": y},
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_location_x(
        self,
        x: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.location['x'] == x."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.location["x"]
            return (actual == x, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have location x={x}",
            expected=x,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_location_y(
        self,
        y: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.location['y'] == y."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.location["y"]
            return (actual == y, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have location y={y}",
            expected=y,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_size(
        self,
        width: int,
        height: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.size == {'width': width, 'height': height}."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            sz = el.size
            actual = {"width": sz["width"], "height": sz["height"]}
            return (actual == {"width": width, "height": height}, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have size ({width}x{height})",
            expected={"width": width, "height": height},
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_size_width(
        self,
        width: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.size['width'] == width."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.size["width"]
            return (actual == width, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have size width={width}",
            expected=width,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_size_height(
        self,
        height: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.size['height'] == height."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.size["height"]
            return (actual == height, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have size height={height}",
            expected=height,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_rect(
        self,
        x: int,
        y: int,
        width: int,
        height: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.rect matches all four values."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            rect = el.rect
            actual = {
                "x": rect["x"],
                "y": rect["y"],
                "width": rect["width"],
                "height": rect["height"],
            }
            expected = {"x": x, "y": y, "width": width, "height": height}
            return (actual == expected, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have rect ({x}, {y}, {width}x{height})",
            expected={"x": x, "y": y, "width": width, "height": height},
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_location_greater_than(
        self,
        x: int | None = None,
        y: int | None = None,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.location x and/or y are greater than given values."""
        if x is None and y is None:
            raise ValueError("At least one of x or y must be provided")
        el = self._target

        def condition() -> tuple[bool, Any]:
            loc = el.location
            actual = {"x": loc["x"], "y": loc["y"]}
            checks = []
            if x is not None:
                checks.append(loc["x"] > x)
            if y is not None:
                checks.append(loc["y"] > y)
            return (all(checks), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have location > ({x}, {y})",
            expected=f"x>{x}, y>{y}",
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_location_less_than(
        self,
        x: int | None = None,
        y: int | None = None,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.location x and/or y are less than given values."""
        if x is None and y is None:
            raise ValueError("At least one of x or y must be provided")
        el = self._target

        def condition() -> tuple[bool, Any]:
            loc = el.location
            actual = {"x": loc["x"], "y": loc["y"]}
            checks = []
            if x is not None:
                checks.append(loc["x"] < x)
            if y is not None:
                checks.append(loc["y"] < y)
            return (all(checks), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have location < ({x}, {y})",
            expected=f"x<{x}, y<{y}",
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_size_greater_than(
        self,
        width: int | None = None,
        height: int | None = None,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.size width and/or height are greater than given values."""
        if width is None and height is None:
            raise ValueError("At least one of width or height must be provided")
        el = self._target

        def condition() -> tuple[bool, Any]:
            sz = el.size
            actual = {"width": sz["width"], "height": sz["height"]}
            checks = []
            if width is not None:
                checks.append(sz["width"] > width)
            if height is not None:
                checks.append(sz["height"] > height)
            return (all(checks), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have size > ({width}, {height})",
            expected=f"w>{width}, h>{height}",
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_size_less_than(
        self,
        width: int | None = None,
        height: int | None = None,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.size width and/or height are less than given values."""
        if width is None and height is None:
            raise ValueError("At least one of width or height must be provided")
        el = self._target

        def condition() -> tuple[bool, Any]:
            sz = el.size
            actual = {"width": sz["width"], "height": sz["height"]}
            checks = []
            if width is not None:
                checks.append(sz["width"] < width)
            if height is not None:
                checks.append(sz["height"] < height)
            return (all(checks), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have size < ({width}, {height})",
            expected=f"w<{width}, h<{height}",
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_location_once_scrolled_into_view(
        self,
        x: int,
        y: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.location_once_scrolled_into_view == {'x': x, 'y': y}."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            loc = el.location_once_scrolled_into_view
            actual = {"x": loc["x"], "y": loc["y"]}
            return (actual == {"x": x, "y": y}, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have location once scrolled into view ({x}, {y})",
            expected={"x": x, "y": y},
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    # --- Accessibility (Selenium 4+) ---

    def to_have_aria_role(
        self,
        role: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.aria_role == role."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.aria_role
            return (actual == role, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have aria role {role!r}",
            expected=role,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_aria_role_contains(
        self,
        role: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert role in element.aria_role."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.aria_role
            return (role in (actual or ""), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have aria role containing {role!r}",
            expected=role,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_aria_role_in_list(
        self,
        *roles: str,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.aria_role is one of *roles."""
        if not roles:
            raise ValueError("At least one role must be provided")
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.aria_role
            return (actual in roles, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have aria role in {list(roles)!r}",
            expected=list(roles),
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_accessible_name(
        self,
        name: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.accessible_name == name."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.accessible_name
            return (actual == name, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have accessible name {name!r}",
            expected=name,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_accessible_name_contains(
        self,
        name: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert name in element.accessible_name."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.accessible_name
            return (name in (actual or ""), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have accessible name containing {name!r}",
            expected=name,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    # --- Shadow DOM ---

    def to_have_js_property(
        self,
        name: str,
        value: Any,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element JS property == value via execute_script."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            driver = getattr(el, "parent", None)
            if driver is None:
                return (False, "no driver")
            actual = driver.execute_script("return arguments[0][arguments[1]];", el, name)
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have JS property {name!r}={value!r}",
            expected=value,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_shadow_root(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.shadow_root is not None."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.shadow_root
            return (actual is not None, actual)

        self._run_assertion(
            condition=condition,
            condition_name="to have shadow root",
            expected="not None",
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    def to_have_shadow_root_absent(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element.shadow_root is None."""
        el = self._target

        def condition() -> tuple[bool, Any]:
            actual = el.shadow_root
            return (actual is None, actual)

        self._run_assertion(
            condition=condition,
            condition_name="to have shadow root absent",
            expected="None",
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    # --- Overrides ---

    def _entity_description(self) -> str:
        el = self._target
        try:
            tag = el.tag_name
            elem_id = el.get_attribute("id")
            if elem_id:
                return f"<{tag} id={elem_id!r}>"
            return f"<{tag}>"
        except Exception:
            return repr(el)

    def _get_element_html(self) -> str | None:
        el = self._target
        try:
            html = el.get_attribute("outerHTML")
            return html if html else None
        except Exception:
            return None

to_be_absent

to_be_absent(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element doesn't exist (raises StaleElementReferenceException or NoSuchElementException).

Source code in selenium_expect/assertions/element.py
def to_be_absent(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element doesn't exist (raises StaleElementReferenceException
    or NoSuchElementException)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        try:
            el.tag_name  # noqa: B018
            return (False, "present")
        except Exception:
            return (True, "absent")

    self._run_assertion(
        condition=condition,
        condition_name="to be absent",
        expected=True,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_checked

to_be_checked(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.is_selected() == True (checkbox/radio).

Source code in selenium_expect/assertions/element.py
def to_be_checked(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.is_selected() == True (checkbox/radio)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        return (el.is_selected(), el.is_selected())

    self._run_assertion(
        condition=condition,
        condition_name="to be checked",
        expected=True,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_clickable

to_be_clickable(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.is_displayed() and element.is_enabled().

Source code in selenium_expect/assertions/element.py
def to_be_clickable(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.is_displayed() and element.is_enabled()."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        displayed = el.is_displayed()
        enabled = el.is_enabled()
        clickable = displayed and enabled
        return (clickable, {"displayed": displayed, "enabled": enabled})

    self._run_assertion(
        condition=condition,
        condition_name="to be clickable",
        expected=True,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_disabled

to_be_disabled(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.is_enabled() == False.

Source code in selenium_expect/assertions/element.py
def to_be_disabled(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.is_enabled() == False."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        enabled = el.is_enabled()
        return (not enabled, enabled)

    self._run_assertion(
        condition=condition,
        condition_name="to be disabled",
        expected=False,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_editable

to_be_editable(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element is editable (input/textarea, not readonly, not disabled).

Source code in selenium_expect/assertions/element.py
def to_be_editable(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element is editable (input/textarea, not readonly, not disabled)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        tag = el.tag_name
        if tag not in ("input", "textarea"):
            return (False, f"tag={tag!r}")
        if not el.is_enabled():
            return (False, "disabled")
        readonly = el.get_attribute("readonly")
        if readonly is not None:
            return (False, "readonly")
        return (True, "editable")

    self._run_assertion(
        condition=condition,
        condition_name="to be editable",
        expected=True,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_empty

to_be_empty(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.text.strip() == '' (no visible text).

Source code in selenium_expect/assertions/element.py
def to_be_empty(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.text.strip() == '' (no visible text)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.text
        return ((actual or "").strip() == "", actual)

    self._run_assertion(
        condition=condition,
        condition_name="to be empty",
        expected="",
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_enabled

to_be_enabled(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.is_enabled() == True.

Source code in selenium_expect/assertions/element.py
def to_be_enabled(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.is_enabled() == True."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        return (el.is_enabled(), el.is_enabled())

    self._run_assertion(
        condition=condition,
        condition_name="to be enabled",
        expected=True,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_focused

to_be_focused(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element is the active element (driver.switch_to.active_element == element).

Source code in selenium_expect/assertions/element.py
def to_be_focused(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element is the active element (driver.switch_to.active_element == element)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        driver = getattr(el, "parent", None)
        if driver is None:
            return (False, "no driver")
        active = driver.switch_to.active_element
        return (active.id == el.id, active)

    self._run_assertion(
        condition=condition,
        condition_name="to be focused",
        expected=True,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_hidden

to_be_hidden(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.is_displayed() == False.

Source code in selenium_expect/assertions/element.py
def to_be_hidden(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.is_displayed() == False."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        displayed = el.is_displayed()
        return (not displayed, displayed)

    self._run_assertion(
        condition=condition,
        condition_name="to be hidden",
        expected=False,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_present

to_be_present(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element exists in DOM (element.tag_name doesn't raise).

Source code in selenium_expect/assertions/element.py
def to_be_present(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element exists in DOM (element.tag_name doesn't raise)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        try:
            tag = el.tag_name
            return (True, tag)
        except Exception as exc:
            return (False, str(exc))

    self._run_assertion(
        condition=condition,
        condition_name="to be present",
        expected=True,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_readonly

to_be_readonly(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element is readonly (get_attribute('readonly') is not None).

Source code in selenium_expect/assertions/element.py
def to_be_readonly(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element is readonly (get_attribute('readonly') is not None)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute("readonly")
        return (actual is not None, actual)

    self._run_assertion(
        condition=condition,
        condition_name="to be readonly",
        expected="not None",
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_selected

to_be_selected(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.is_selected() == True (option/checkbox/radio).

Source code in selenium_expect/assertions/element.py
def to_be_selected(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.is_selected() == True (option/checkbox/radio)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        return (el.is_selected(), el.is_selected())

    self._run_assertion(
        condition=condition,
        condition_name="to be selected",
        expected=True,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_stale

to_be_stale(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element is stale (any access raises StaleElementReferenceException).

Source code in selenium_expect/assertions/element.py
def to_be_stale(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element is stale (any access raises StaleElementReferenceException)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        try:
            el.tag_name  # noqa: B018
            return (False, "not stale")
        except Exception:
            return (True, "stale")

    self._run_assertion(
        condition=condition,
        condition_name="to be stale",
        expected=True,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_unchecked

to_be_unchecked(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.is_selected() == False (semantic alias for not_.to_be_checked()).

Source code in selenium_expect/assertions/element.py
def to_be_unchecked(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.is_selected() == False (semantic alias for not_.to_be_checked())."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        selected = el.is_selected()
        return (not selected, selected)

    self._run_assertion(
        condition=condition,
        condition_name="to be unchecked",
        expected=False,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_unselected

to_be_unselected(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.is_selected() == False (semantic alias for not_.to_be_selected()).

Source code in selenium_expect/assertions/element.py
def to_be_unselected(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.is_selected() == False (semantic alias for not_.to_be_selected())."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        selected = el.is_selected()
        return (not selected, selected)

    self._run_assertion(
        condition=condition,
        condition_name="to be unselected",
        expected=False,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_be_visible

to_be_visible(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.is_displayed() == True.

Source code in selenium_expect/assertions/element.py
def to_be_visible(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.is_displayed() == True."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        return (el.is_displayed(), el.is_displayed())

    self._run_assertion(
        condition=condition,
        condition_name="to be visible",
        expected=True,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_contain_class

to_contain_class(class_name: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert class_name in element.get_attribute('class').split() (alias of to_have_class).

Source code in selenium_expect/assertions/element.py
def to_contain_class(
    self,
    class_name: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert class_name in element.get_attribute('class').split() (alias of to_have_class)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute("class")
        classes = (actual or "").split()
        return (class_name in classes, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to contain class {class_name!r}",
        expected=class_name,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_accessible_name

to_have_accessible_name(name: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.accessible_name == name.

Source code in selenium_expect/assertions/element.py
def to_have_accessible_name(
    self,
    name: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.accessible_name == name."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.accessible_name
        return (actual == name, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have accessible name {name!r}",
        expected=name,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_accessible_name_contains

to_have_accessible_name_contains(name: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert name in element.accessible_name.

Source code in selenium_expect/assertions/element.py
def to_have_accessible_name_contains(
    self,
    name: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert name in element.accessible_name."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.accessible_name
        return (name in (actual or ""), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have accessible name containing {name!r}",
        expected=name,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_all_classes

to_have_all_classes(*classes: str, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element has all specified classes.

Source code in selenium_expect/assertions/element.py
def to_have_all_classes(
    self,
    *classes: str,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element has all specified classes."""
    if not classes:
        raise ValueError("At least one class must be provided")
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute("class")
        elem_classes = set((actual or "").split())
        return (set(classes).issubset(elem_classes), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have all classes {list(classes)!r}",
        expected=list(classes),
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_aria_role

to_have_aria_role(role: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.aria_role == role.

Source code in selenium_expect/assertions/element.py
def to_have_aria_role(
    self,
    role: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.aria_role == role."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.aria_role
        return (actual == role, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have aria role {role!r}",
        expected=role,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_aria_role_contains

to_have_aria_role_contains(role: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert role in element.aria_role.

Source code in selenium_expect/assertions/element.py
def to_have_aria_role_contains(
    self,
    role: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert role in element.aria_role."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.aria_role
        return (role in (actual or ""), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have aria role containing {role!r}",
        expected=role,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_aria_role_in_list

to_have_aria_role_in_list(*roles: str, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.aria_role is one of *roles.

Source code in selenium_expect/assertions/element.py
def to_have_aria_role_in_list(
    self,
    *roles: str,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.aria_role is one of *roles."""
    if not roles:
        raise ValueError("At least one role must be provided")
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.aria_role
        return (actual in roles, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have aria role in {list(roles)!r}",
        expected=list(roles),
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_attribute

to_have_attribute(name: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.get_attribute(name) == value.

Source code in selenium_expect/assertions/element.py
def to_have_attribute(
    self,
    name: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.get_attribute(name) == value."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute(name)
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have attribute {name!r}={value!r}",
        expected=value,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_attribute_absent

to_have_attribute_absent(name: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.get_attribute(name) is None.

Source code in selenium_expect/assertions/element.py
def to_have_attribute_absent(
    self,
    name: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.get_attribute(name) is None."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute(name)
        return (actual is None, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have attribute {name!r} absent",
        expected="absent",
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_attribute_contains

to_have_attribute_contains(name: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert value in element.get_attribute(name).

Source code in selenium_expect/assertions/element.py
def to_have_attribute_contains(
    self,
    name: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert value in element.get_attribute(name)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute(name)
        return (value in (actual or ""), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have attribute {name!r} containing {value!r}",
        expected=value,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_attribute_empty

to_have_attribute_empty(name: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.get_attribute(name) == '' or None.

Source code in selenium_expect/assertions/element.py
def to_have_attribute_empty(
    self,
    name: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.get_attribute(name) == '' or None."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute(name)
        return (actual is None or actual == "", actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have attribute {name!r} empty",
        expected="empty or None",
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_attribute_in_list

to_have_attribute_in_list(name: str, values: list[str], *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.get_attribute(name) in values.

Source code in selenium_expect/assertions/element.py
def to_have_attribute_in_list(
    self,
    name: str,
    values: list[str],
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.get_attribute(name) in values."""
    if not values:
        raise ValueError("values list must not be empty")
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute(name)
        return (actual in values, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have attribute {name!r} in {values!r}",
        expected=values,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_attribute_matches

to_have_attribute_matches(name: str, pattern: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert re.search(pattern, element.get_attribute(name)).

Source code in selenium_expect/assertions/element.py
def to_have_attribute_matches(
    self,
    name: str,
    pattern: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert re.search(pattern, element.get_attribute(name))."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute(name)
        return (re.search(pattern, actual or "") is not None, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have attribute {name!r} matching {pattern!r}",
        expected=pattern,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_attribute_present

to_have_attribute_present(name: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.get_attribute(name) is not None.

Source code in selenium_expect/assertions/element.py
def to_have_attribute_present(
    self,
    name: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.get_attribute(name) is not None."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute(name)
        return (actual is not None, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have attribute {name!r} present",
        expected="present",
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_class

to_have_class(class_name: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert class_name in element.get_attribute('class').split().

Source code in selenium_expect/assertions/element.py
def to_have_class(
    self,
    class_name: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert class_name in element.get_attribute('class').split()."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute("class")
        classes = (actual or "").split()
        return (class_name in classes, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have class {class_name!r}",
        expected=class_name,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_class_contains

to_have_class_contains(class_name: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert class_name in element.get_attribute('class') (substring).

Source code in selenium_expect/assertions/element.py
def to_have_class_contains(
    self,
    class_name: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert class_name in element.get_attribute('class') (substring)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute("class")
        return (class_name in (actual or ""), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have class containing {class_name!r}",
        expected=class_name,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_class_in_list

to_have_class_in_list(*classes: str, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element has at least one of the specified classes.

Source code in selenium_expect/assertions/element.py
def to_have_class_in_list(
    self,
    *classes: str,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element has at least one of the specified classes."""
    if not classes:
        raise ValueError("At least one class must be provided")
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute("class")
        elem_classes = set((actual or "").split())
        return (bool(elem_classes & set(classes)), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have class in {list(classes)!r}",
        expected=list(classes),
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_class_matching

to_have_class_matching(pattern: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert any class in element.get_attribute('class').split() matches pattern.

Source code in selenium_expect/assertions/element.py
def to_have_class_matching(
    self,
    pattern: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert any class in element.get_attribute('class').split() matches pattern."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute("class")
        classes = (actual or "").split()
        return (any(re.search(pattern, c) for c in classes), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have class matching {pattern!r}",
        expected=pattern,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_css_property

to_have_css_property(name: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.value_of_css_property(name) == value.

Source code in selenium_expect/assertions/element.py
def to_have_css_property(
    self,
    name: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.value_of_css_property(name) == value."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.value_of_css_property(name)
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have CSS {name!r}={value!r}",
        expected=value,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_css_property_contains

to_have_css_property_contains(name: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert value in element.value_of_css_property(name).

Source code in selenium_expect/assertions/element.py
def to_have_css_property_contains(
    self,
    name: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert value in element.value_of_css_property(name)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.value_of_css_property(name)
        return (value in (actual or ""), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have CSS {name!r} containing {value!r}",
        expected=value,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_css_property_matches

to_have_css_property_matches(name: str, pattern: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert re.search(pattern, element.value_of_css_property(name)).

Source code in selenium_expect/assertions/element.py
def to_have_css_property_matches(
    self,
    name: str,
    pattern: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert re.search(pattern, element.value_of_css_property(name))."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.value_of_css_property(name)
        return (re.search(pattern, actual or "") is not None, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have CSS {name!r} matching {pattern!r}",
        expected=pattern,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_dom_attribute

to_have_dom_attribute(name: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.get_dom_attribute(name) == value.

Source code in selenium_expect/assertions/element.py
def to_have_dom_attribute(
    self,
    name: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.get_dom_attribute(name) == value."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_dom_attribute(name)
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have DOM attribute {name!r}={value!r}",
        expected=value,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_dom_attribute_contains

to_have_dom_attribute_contains(name: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert value in element.get_dom_attribute(name).

Source code in selenium_expect/assertions/element.py
def to_have_dom_attribute_contains(
    self,
    name: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert value in element.get_dom_attribute(name)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_dom_attribute(name)
        return (value in (actual or ""), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have DOM attribute {name!r} containing {value!r}",
        expected=value,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_id

to_have_id(id: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.get_attribute('id') == id.

Source code in selenium_expect/assertions/element.py
def to_have_id(
    self,
    id: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.get_attribute('id') == id."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute("id")
        return (actual == id, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have id {id!r}",
        expected=id,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_js_property

to_have_js_property(name: str, value: Any, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element JS property == value via execute_script.

Source code in selenium_expect/assertions/element.py
def to_have_js_property(
    self,
    name: str,
    value: Any,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element JS property == value via execute_script."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        driver = getattr(el, "parent", None)
        if driver is None:
            return (False, "no driver")
        actual = driver.execute_script("return arguments[0][arguments[1]];", el, name)
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have JS property {name!r}={value!r}",
        expected=value,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_location

to_have_location(x: int, y: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.location == {'x': x, 'y': y}.

Source code in selenium_expect/assertions/element.py
def to_have_location(
    self,
    x: int,
    y: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.location == {'x': x, 'y': y}."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        loc = el.location
        actual = {"x": loc["x"], "y": loc["y"]}
        return (actual == {"x": x, "y": y}, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have location ({x}, {y})",
        expected={"x": x, "y": y},
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_location_greater_than

to_have_location_greater_than(x: int | None = None, y: int | None = None, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.location x and/or y are greater than given values.

Source code in selenium_expect/assertions/element.py
def to_have_location_greater_than(
    self,
    x: int | None = None,
    y: int | None = None,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.location x and/or y are greater than given values."""
    if x is None and y is None:
        raise ValueError("At least one of x or y must be provided")
    el = self._target

    def condition() -> tuple[bool, Any]:
        loc = el.location
        actual = {"x": loc["x"], "y": loc["y"]}
        checks = []
        if x is not None:
            checks.append(loc["x"] > x)
        if y is not None:
            checks.append(loc["y"] > y)
        return (all(checks), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have location > ({x}, {y})",
        expected=f"x>{x}, y>{y}",
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_location_less_than

to_have_location_less_than(x: int | None = None, y: int | None = None, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.location x and/or y are less than given values.

Source code in selenium_expect/assertions/element.py
def to_have_location_less_than(
    self,
    x: int | None = None,
    y: int | None = None,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.location x and/or y are less than given values."""
    if x is None and y is None:
        raise ValueError("At least one of x or y must be provided")
    el = self._target

    def condition() -> tuple[bool, Any]:
        loc = el.location
        actual = {"x": loc["x"], "y": loc["y"]}
        checks = []
        if x is not None:
            checks.append(loc["x"] < x)
        if y is not None:
            checks.append(loc["y"] < y)
        return (all(checks), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have location < ({x}, {y})",
        expected=f"x<{x}, y<{y}",
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_location_once_scrolled_into_view

to_have_location_once_scrolled_into_view(x: int, y: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.location_once_scrolled_into_view == {'x': x, 'y': y}.

Source code in selenium_expect/assertions/element.py
def to_have_location_once_scrolled_into_view(
    self,
    x: int,
    y: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.location_once_scrolled_into_view == {'x': x, 'y': y}."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        loc = el.location_once_scrolled_into_view
        actual = {"x": loc["x"], "y": loc["y"]}
        return (actual == {"x": x, "y": y}, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have location once scrolled into view ({x}, {y})",
        expected={"x": x, "y": y},
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_location_x

to_have_location_x(x: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.location['x'] == x.

Source code in selenium_expect/assertions/element.py
def to_have_location_x(
    self,
    x: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.location['x'] == x."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.location["x"]
        return (actual == x, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have location x={x}",
        expected=x,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_location_y

to_have_location_y(y: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.location['y'] == y.

Source code in selenium_expect/assertions/element.py
def to_have_location_y(
    self,
    y: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.location['y'] == y."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.location["y"]
        return (actual == y, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have location y={y}",
        expected=y,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_property

to_have_property(name: str, value: Any, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.get_property(name) == value.

Source code in selenium_expect/assertions/element.py
def to_have_property(
    self,
    name: str,
    value: Any,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.get_property(name) == value."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_property(name)
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have property {name!r}={value!r}",
        expected=value,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_property_contains

to_have_property_contains(name: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert value in str(element.get_property(name)).

Source code in selenium_expect/assertions/element.py
def to_have_property_contains(
    self,
    name: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert value in str(element.get_property(name))."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_property(name)
        if actual is None:
            return (False, actual)
        return (value in str(actual), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have property {name!r} containing {value!r}",
        expected=value,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_rect

to_have_rect(x: int, y: int, width: int, height: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.rect matches all four values.

Source code in selenium_expect/assertions/element.py
def to_have_rect(
    self,
    x: int,
    y: int,
    width: int,
    height: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.rect matches all four values."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        rect = el.rect
        actual = {
            "x": rect["x"],
            "y": rect["y"],
            "width": rect["width"],
            "height": rect["height"],
        }
        expected = {"x": x, "y": y, "width": width, "height": height}
        return (actual == expected, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have rect ({x}, {y}, {width}x{height})",
        expected={"x": x, "y": y, "width": width, "height": height},
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_shadow_root

to_have_shadow_root(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.shadow_root is not None.

Source code in selenium_expect/assertions/element.py
def to_have_shadow_root(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.shadow_root is not None."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.shadow_root
        return (actual is not None, actual)

    self._run_assertion(
        condition=condition,
        condition_name="to have shadow root",
        expected="not None",
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_shadow_root_absent

to_have_shadow_root_absent(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.shadow_root is None.

Source code in selenium_expect/assertions/element.py
def to_have_shadow_root_absent(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.shadow_root is None."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.shadow_root
        return (actual is None, actual)

    self._run_assertion(
        condition=condition,
        condition_name="to have shadow root absent",
        expected="None",
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_size

to_have_size(width: int, height: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.size == {'width': width, 'height': height}.

Source code in selenium_expect/assertions/element.py
def to_have_size(
    self,
    width: int,
    height: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.size == {'width': width, 'height': height}."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        sz = el.size
        actual = {"width": sz["width"], "height": sz["height"]}
        return (actual == {"width": width, "height": height}, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have size ({width}x{height})",
        expected={"width": width, "height": height},
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_size_greater_than

to_have_size_greater_than(width: int | None = None, height: int | None = None, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.size width and/or height are greater than given values.

Source code in selenium_expect/assertions/element.py
def to_have_size_greater_than(
    self,
    width: int | None = None,
    height: int | None = None,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.size width and/or height are greater than given values."""
    if width is None and height is None:
        raise ValueError("At least one of width or height must be provided")
    el = self._target

    def condition() -> tuple[bool, Any]:
        sz = el.size
        actual = {"width": sz["width"], "height": sz["height"]}
        checks = []
        if width is not None:
            checks.append(sz["width"] > width)
        if height is not None:
            checks.append(sz["height"] > height)
        return (all(checks), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have size > ({width}, {height})",
        expected=f"w>{width}, h>{height}",
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_size_height

to_have_size_height(height: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.size['height'] == height.

Source code in selenium_expect/assertions/element.py
def to_have_size_height(
    self,
    height: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.size['height'] == height."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.size["height"]
        return (actual == height, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have size height={height}",
        expected=height,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_size_less_than

to_have_size_less_than(width: int | None = None, height: int | None = None, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.size width and/or height are less than given values.

Source code in selenium_expect/assertions/element.py
def to_have_size_less_than(
    self,
    width: int | None = None,
    height: int | None = None,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.size width and/or height are less than given values."""
    if width is None and height is None:
        raise ValueError("At least one of width or height must be provided")
    el = self._target

    def condition() -> tuple[bool, Any]:
        sz = el.size
        actual = {"width": sz["width"], "height": sz["height"]}
        checks = []
        if width is not None:
            checks.append(sz["width"] < width)
        if height is not None:
            checks.append(sz["height"] < height)
        return (all(checks), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have size < ({width}, {height})",
        expected=f"w<{width}, h<{height}",
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_size_width

to_have_size_width(width: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.size['width'] == width.

Source code in selenium_expect/assertions/element.py
def to_have_size_width(
    self,
    width: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.size['width'] == width."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.size["width"]
        return (actual == width, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have size width={width}",
        expected=width,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_tag

to_have_tag(tag: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.tag_name == tag.

Source code in selenium_expect/assertions/element.py
def to_have_tag(
    self,
    tag: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.tag_name == tag."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.tag_name
        return (actual == tag, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have tag {tag!r}",
        expected=tag,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_text

to_have_text(text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.text == text.

Source code in selenium_expect/assertions/element.py
def to_have_text(
    self,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.text == text."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.text
        return (actual == text, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have text {text!r}",
        expected=text,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_text_contains

to_have_text_contains(text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert text in element.text.

Source code in selenium_expect/assertions/element.py
def to_have_text_contains(
    self,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert text in element.text."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.text
        return (text in (actual or ""), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have text containing {text!r}",
        expected=text,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_text_empty

to_have_text_empty(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.text == ''.

Source code in selenium_expect/assertions/element.py
def to_have_text_empty(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.text == ''."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.text
        return (actual == "", actual)

    self._run_assertion(
        condition=condition,
        condition_name="to have text empty",
        expected="",
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_text_ending_with

to_have_text_ending_with(suffix: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.text.endswith(suffix).

Source code in selenium_expect/assertions/element.py
def to_have_text_ending_with(
    self,
    suffix: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.text.endswith(suffix)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.text
        return ((actual or "").endswith(suffix), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have text ending with {suffix!r}",
        expected=suffix,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_text_in_list

to_have_text_in_list(*texts: str, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.text is one of *texts.

Source code in selenium_expect/assertions/element.py
def to_have_text_in_list(
    self,
    *texts: str,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.text is one of *texts."""
    if not texts:
        raise ValueError("At least one text must be provided")
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.text
        return (actual in texts, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have text in {list(texts)!r}",
        expected=list(texts),
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_text_matches

to_have_text_matches(pattern: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert re.search(pattern, element.text).

Source code in selenium_expect/assertions/element.py
def to_have_text_matches(
    self,
    pattern: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert re.search(pattern, element.text)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.text
        return (re.search(pattern, actual or "") is not None, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have text matching {pattern!r}",
        expected=pattern,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_text_not_empty

to_have_text_not_empty(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.text != ''.

Source code in selenium_expect/assertions/element.py
def to_have_text_not_empty(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.text != ''."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.text
        return (bool(actual), actual)

    self._run_assertion(
        condition=condition,
        condition_name="to have text not empty",
        expected="non-empty",
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_text_starting_with

to_have_text_starting_with(prefix: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.text.startswith(prefix).

Source code in selenium_expect/assertions/element.py
def to_have_text_starting_with(
    self,
    prefix: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.text.startswith(prefix)."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.text
        return ((actual or "").startswith(prefix), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have text starting with {prefix!r}",
        expected=prefix,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_value

to_have_value(value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.get_attribute('value') == value.

Source code in selenium_expect/assertions/element.py
def to_have_value(
    self,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.get_attribute('value') == value."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute("value")
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have value {value!r}",
        expected=value,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_value_contains

to_have_value_contains(value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert value in element.get_attribute('value').

Source code in selenium_expect/assertions/element.py
def to_have_value_contains(
    self,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert value in element.get_attribute('value')."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute("value")
        return (value in (actual or ""), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have value containing {value!r}",
        expected=value,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_value_in_list

to_have_value_in_list(values: list[str], *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element.get_attribute('value') in values.

Source code in selenium_expect/assertions/element.py
def to_have_value_in_list(
    self,
    values: list[str],
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element.get_attribute('value') in values."""
    if not values:
        raise ValueError("values list must not be empty")
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute("value")
        return (actual in values, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have value in {values!r}",
        expected=values,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

to_have_value_matches

to_have_value_matches(pattern: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert re.search(pattern, element.get_attribute('value')).

Source code in selenium_expect/assertions/element.py
def to_have_value_matches(
    self,
    pattern: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert re.search(pattern, element.get_attribute('value'))."""
    el = self._target

    def condition() -> tuple[bool, Any]:
        actual = el.get_attribute("value")
        return (re.search(pattern, actual or "") is not None, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have value matching {pattern!r}",
        expected=pattern,
        entity=self._entity_description(),
        timeout=timeout,
        polling=polling,
    )

ExpectDriver

Assertions for WebDriver and page-level state.

Key method categories:

  • Title: to_have_title, to_have_title_contains, to_have_title_matches
  • URL: to_have_url, to_have_url_contains, to_have_url_matches
  • State: to_have_ready_state
  • Windows: to_have_window_count, to_have_window_count_greater_than, to_have_window_handles
  • Browser: to_have_browser_name, to_have_capability
  • Page source: to_have_page_source_contains
  • Window geometry: to_have_position, to_have_size, to_have_rect
  • Active element: to_have_active_element_tag, to_have_active_element_attribute, to_have_active_element_text, to_have_active_element_visible, to_have_active_element_enabled

selenium_expect.assertions.driver.ExpectDriver

Bases: ExpectCookie, ExpectJS, ExpectIframe, ExpectWindow, AssertionMixin

Assertions for WebDriver / page-level state.

Inherits cookie, JS, iframe, and window assertions via multiple inheritance so all driver-level assertions are available via expect(driver).

Source code in selenium_expect/assertions/driver.py
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
class ExpectDriver(ExpectCookie, ExpectJS, ExpectIframe, ExpectWindow, AssertionMixin):
    """Assertions for WebDriver / page-level state.

    Inherits cookie, JS, iframe, and window assertions via multiple
    inheritance so all driver-level assertions are available via
    ``expect(driver)``.
    """

    def __init__(
        self,
        target: WebDriver,
        config: ExpectConfig | None = None,
        message: str | None = None,
        negate: bool = False,
    ) -> None:
        super().__init__(target=target, config=config, message=message, negate=negate)

    # --- Title ---

    def to_have_title(
        self,
        title: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.title == title."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.title
            return (actual == title, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have title {title!r}",
            expected=title,
            entity="page",
            timeout=timeout,
            polling=polling,
        )

    def to_have_title_contains(
        self,
        title: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert title in driver.title."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.title
            return (title in (actual or ""), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have title containing {title!r}",
            expected=title,
            entity="page",
            timeout=timeout,
            polling=polling,
        )

    def to_have_title_matches(
        self,
        pattern: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert re.search(pattern, driver.title)."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.title
            return (re.search(pattern, actual or "") is not None, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have title matching {pattern!r}",
            expected=pattern,
            entity="page",
            timeout=timeout,
            polling=polling,
        )

    # --- URL ---

    def to_have_url(
        self,
        url: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.current_url == url."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.current_url
            return (actual == url, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have URL {url!r}",
            expected=url,
            entity="page",
            timeout=timeout,
            polling=polling,
        )

    def to_have_url_contains(
        self,
        url: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert url in driver.current_url."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.current_url
            return (url in (actual or ""), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have URL containing {url!r}",
            expected=url,
            entity="page",
            timeout=timeout,
            polling=polling,
        )

    def to_have_url_matches(
        self,
        pattern: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert re.search(pattern, driver.current_url)."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.current_url
            return (re.search(pattern, actual or "") is not None, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have URL matching {pattern!r}",
            expected=pattern,
            entity="page",
            timeout=timeout,
            polling=polling,
        )

    def to_have_url_changes(
        self,
        url: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.current_url != url (URL has changed from the given value)."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.current_url
            return (actual != url, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have URL changed from {url!r}",
            expected=f"!= {url!r}",
            entity="page",
            timeout=timeout,
            polling=polling,
        )

    # --- Ready state ---

    def to_have_ready_state(
        self,
        state: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert document.readyState == state (e.g. 'complete', 'interactive', 'loading')."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.execute_script("return document.readyState;")
            return (actual == state, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have ready state {state!r}",
            expected=state,
            entity="page",
            timeout=timeout,
            polling=polling,
        )

    # --- Windows / tabs ---

    def to_have_window_count(
        self,
        count: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(driver.window_handles) == count."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(driver.window_handles)
            return (actual == count, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have window count {count}",
            expected=count,
            entity="browser",
            timeout=timeout,
            polling=polling,
        )

    def to_have_window_count_greater_than(
        self,
        n: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(driver.window_handles) > n."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(driver.window_handles)
            return (actual > n, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have window count > {n}",
            expected=f">{n}",
            entity="browser",
            timeout=timeout,
            polling=polling,
        )

    def to_have_window_count_less_than(
        self,
        n: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(driver.window_handles) < n."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(driver.window_handles)
            return (actual < n, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have window count < {n}",
            expected=f"<{n}",
            entity="browser",
            timeout=timeout,
            polling=polling,
        )

    def to_have_window_handle(
        self,
        handle: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.current_window_handle == handle."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.current_window_handle
            return (actual == handle, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have window handle {handle!r}",
            expected=handle,
            entity="browser",
            timeout=timeout,
            polling=polling,
        )

    def to_have_new_window_opened(
        self,
        previous_handles: list[str],
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert that a new window has opened (current handles > previous handles)."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            current = driver.window_handles
            new_handles = [h for h in current if h not in previous_handles]
            return (len(new_handles) > 0, new_handles)

        self._run_assertion(
            condition=condition,
            condition_name="to have new window opened",
            expected="new handle",
            entity="browser",
            timeout=timeout,
            polling=polling,
        )

    # --- Browser / capabilities ---

    def to_have_browser_name(
        self,
        name: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.name == name."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.name
            return (actual == name, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have browser name {name!r}",
            expected=name,
            entity="browser",
            timeout=timeout,
            polling=polling,
        )

    def to_have_orientation(
        self,
        orientation: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.orientation == orientation."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.orientation
            return (actual == orientation, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have orientation {orientation!r}",
            expected=orientation,
            entity="browser",
            timeout=timeout,
            polling=polling,
        )

    def to_have_capability(
        self,
        key: str,
        value: Any,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.capabilities[key] == value."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            caps = driver.capabilities
            actual = caps.get(key) if caps else None
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have capability {key!r}={value!r}",
            expected=value,
            entity="browser",
            timeout=timeout,
            polling=polling,
        )

    def to_have_capability_contains(
        self,
        key: str,
        value: Any,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert value in driver.capabilities[key]."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            caps = driver.capabilities
            actual = caps.get(key) if caps else None
            if actual is None:
                return (False, actual)
            return (value in str(actual), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have capability {key!r} containing {value!r}",
            expected=value,
            entity="browser",
            timeout=timeout,
            polling=polling,
        )

    # --- Page source ---

    def to_have_page_source_contains(
        self,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert text in driver.page_source."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.page_source
            return (text in (actual or ""), len(actual) if actual else 0)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have page source containing {text!r}",
            expected=text,
            entity="page",
            timeout=timeout,
            polling=polling,
        )

    def to_have_page_source_matches(
        self,
        pattern: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert re.search(pattern, driver.page_source)."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.page_source
            return (re.search(pattern, actual or "") is not None, len(actual) if actual else 0)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have page source matching {pattern!r}",
            expected=pattern,
            entity="page",
            timeout=timeout,
            polling=polling,
        )

    def to_have_page_source_not_contains(
        self,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert text not in driver.page_source."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.page_source
            return (text not in (actual or ""), len(actual) if actual else 0)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have page source not containing {text!r}",
            expected=f"not {text!r}",
            entity="page",
            timeout=timeout,
            polling=polling,
        )

    # --- Window position / size / rect ---

    def to_have_window_position(
        self,
        x: int,
        y: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.get_window_position() == {'x': x, 'y': y}."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            pos = driver.get_window_position()
            actual = {"x": pos["x"], "y": pos["y"]}
            return (actual == {"x": x, "y": y}, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have window position ({x}, {y})",
            expected={"x": x, "y": y},
            entity="browser",
            timeout=timeout,
            polling=polling,
        )

    def to_have_window_size(
        self,
        width: int,
        height: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.get_window_size() == {'width': width, 'height': height}."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            sz = driver.get_window_size()
            actual = {"width": sz["width"], "height": sz["height"]}
            return (actual == {"width": width, "height": height}, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have window size ({width}x{height})",
            expected={"width": width, "height": height},
            entity="browser",
            timeout=timeout,
            polling=polling,
        )

    def to_have_window_rect(
        self,
        x: int,
        y: int,
        width: int,
        height: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.get_window_rect() matches all four values."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            rect = driver.get_window_rect()
            actual = {
                "x": rect["x"],
                "y": rect["y"],
                "width": rect["width"],
                "height": rect["height"],
            }
            expected = {"x": x, "y": y, "width": width, "height": height}
            return (actual == expected, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have window rect ({x}, {y}, {width}x{height})",
            expected={"x": x, "y": y, "width": width, "height": height},
            entity="browser",
            timeout=timeout,
            polling=polling,
        )

    # --- Active element ---

    def to_have_active_element_tag(
        self,
        tag: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.switch_to.active_element.tag_name == tag."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.switch_to.active_element.tag_name
            return (actual == tag, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have active element tag {tag!r}",
            expected=tag,
            entity="page",
            timeout=timeout,
            polling=polling,
        )

    def to_have_active_element_id(
        self,
        id: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.switch_to.active_element.get_attribute('id') == id."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.switch_to.active_element.get_attribute("id")
            return (actual == id, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have active element id {id!r}",
            expected=id,
            entity="page",
            timeout=timeout,
            polling=polling,
        )

    def to_have_active_element_class(
        self,
        class_name: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert class_name in active_element.get_attribute('class')."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.switch_to.active_element.get_attribute("class")
            classes = (actual or "").split()
            return (class_name in classes, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have active element class {class_name!r}",
            expected=class_name,
            entity="page",
            timeout=timeout,
            polling=polling,
        )

    # --- Overrides ---

    def _entity_description(self) -> str:
        return "WebDriver"

    def _get_element_html(self) -> str | None:
        return None

to_have_active_element_class

to_have_active_element_class(class_name: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert class_name in active_element.get_attribute('class').

Source code in selenium_expect/assertions/driver.py
def to_have_active_element_class(
    self,
    class_name: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert class_name in active_element.get_attribute('class')."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.switch_to.active_element.get_attribute("class")
        classes = (actual or "").split()
        return (class_name in classes, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have active element class {class_name!r}",
        expected=class_name,
        entity="page",
        timeout=timeout,
        polling=polling,
    )

to_have_active_element_id

to_have_active_element_id(id: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.switch_to.active_element.get_attribute('id') == id.

Source code in selenium_expect/assertions/driver.py
def to_have_active_element_id(
    self,
    id: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.switch_to.active_element.get_attribute('id') == id."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.switch_to.active_element.get_attribute("id")
        return (actual == id, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have active element id {id!r}",
        expected=id,
        entity="page",
        timeout=timeout,
        polling=polling,
    )

to_have_active_element_tag

to_have_active_element_tag(tag: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.switch_to.active_element.tag_name == tag.

Source code in selenium_expect/assertions/driver.py
def to_have_active_element_tag(
    self,
    tag: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.switch_to.active_element.tag_name == tag."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.switch_to.active_element.tag_name
        return (actual == tag, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have active element tag {tag!r}",
        expected=tag,
        entity="page",
        timeout=timeout,
        polling=polling,
    )

to_have_browser_name

to_have_browser_name(name: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.name == name.

Source code in selenium_expect/assertions/driver.py
def to_have_browser_name(
    self,
    name: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.name == name."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.name
        return (actual == name, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have browser name {name!r}",
        expected=name,
        entity="browser",
        timeout=timeout,
        polling=polling,
    )

to_have_capability

to_have_capability(key: str, value: Any, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.capabilities[key] == value.

Source code in selenium_expect/assertions/driver.py
def to_have_capability(
    self,
    key: str,
    value: Any,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.capabilities[key] == value."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        caps = driver.capabilities
        actual = caps.get(key) if caps else None
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have capability {key!r}={value!r}",
        expected=value,
        entity="browser",
        timeout=timeout,
        polling=polling,
    )

to_have_capability_contains

to_have_capability_contains(key: str, value: Any, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert value in driver.capabilities[key].

Source code in selenium_expect/assertions/driver.py
def to_have_capability_contains(
    self,
    key: str,
    value: Any,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert value in driver.capabilities[key]."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        caps = driver.capabilities
        actual = caps.get(key) if caps else None
        if actual is None:
            return (False, actual)
        return (value in str(actual), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have capability {key!r} containing {value!r}",
        expected=value,
        entity="browser",
        timeout=timeout,
        polling=polling,
    )

to_have_new_window_opened

to_have_new_window_opened(previous_handles: list[str], *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert that a new window has opened (current handles > previous handles).

Source code in selenium_expect/assertions/driver.py
def to_have_new_window_opened(
    self,
    previous_handles: list[str],
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert that a new window has opened (current handles > previous handles)."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        current = driver.window_handles
        new_handles = [h for h in current if h not in previous_handles]
        return (len(new_handles) > 0, new_handles)

    self._run_assertion(
        condition=condition,
        condition_name="to have new window opened",
        expected="new handle",
        entity="browser",
        timeout=timeout,
        polling=polling,
    )

to_have_orientation

to_have_orientation(orientation: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.orientation == orientation.

Source code in selenium_expect/assertions/driver.py
def to_have_orientation(
    self,
    orientation: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.orientation == orientation."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.orientation
        return (actual == orientation, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have orientation {orientation!r}",
        expected=orientation,
        entity="browser",
        timeout=timeout,
        polling=polling,
    )

to_have_page_source_contains

to_have_page_source_contains(text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert text in driver.page_source.

Source code in selenium_expect/assertions/driver.py
def to_have_page_source_contains(
    self,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert text in driver.page_source."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.page_source
        return (text in (actual or ""), len(actual) if actual else 0)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have page source containing {text!r}",
        expected=text,
        entity="page",
        timeout=timeout,
        polling=polling,
    )

to_have_page_source_matches

to_have_page_source_matches(pattern: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert re.search(pattern, driver.page_source).

Source code in selenium_expect/assertions/driver.py
def to_have_page_source_matches(
    self,
    pattern: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert re.search(pattern, driver.page_source)."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.page_source
        return (re.search(pattern, actual or "") is not None, len(actual) if actual else 0)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have page source matching {pattern!r}",
        expected=pattern,
        entity="page",
        timeout=timeout,
        polling=polling,
    )

to_have_page_source_not_contains

to_have_page_source_not_contains(text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert text not in driver.page_source.

Source code in selenium_expect/assertions/driver.py
def to_have_page_source_not_contains(
    self,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert text not in driver.page_source."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.page_source
        return (text not in (actual or ""), len(actual) if actual else 0)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have page source not containing {text!r}",
        expected=f"not {text!r}",
        entity="page",
        timeout=timeout,
        polling=polling,
    )

to_have_ready_state

to_have_ready_state(state: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert document.readyState == state (e.g. 'complete', 'interactive', 'loading').

Source code in selenium_expect/assertions/driver.py
def to_have_ready_state(
    self,
    state: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert document.readyState == state (e.g. 'complete', 'interactive', 'loading')."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.execute_script("return document.readyState;")
        return (actual == state, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have ready state {state!r}",
        expected=state,
        entity="page",
        timeout=timeout,
        polling=polling,
    )

to_have_title

to_have_title(title: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.title == title.

Source code in selenium_expect/assertions/driver.py
def to_have_title(
    self,
    title: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.title == title."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.title
        return (actual == title, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have title {title!r}",
        expected=title,
        entity="page",
        timeout=timeout,
        polling=polling,
    )

to_have_title_contains

to_have_title_contains(title: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert title in driver.title.

Source code in selenium_expect/assertions/driver.py
def to_have_title_contains(
    self,
    title: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert title in driver.title."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.title
        return (title in (actual or ""), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have title containing {title!r}",
        expected=title,
        entity="page",
        timeout=timeout,
        polling=polling,
    )

to_have_title_matches

to_have_title_matches(pattern: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert re.search(pattern, driver.title).

Source code in selenium_expect/assertions/driver.py
def to_have_title_matches(
    self,
    pattern: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert re.search(pattern, driver.title)."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.title
        return (re.search(pattern, actual or "") is not None, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have title matching {pattern!r}",
        expected=pattern,
        entity="page",
        timeout=timeout,
        polling=polling,
    )

to_have_url

to_have_url(url: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.current_url == url.

Source code in selenium_expect/assertions/driver.py
def to_have_url(
    self,
    url: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.current_url == url."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.current_url
        return (actual == url, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have URL {url!r}",
        expected=url,
        entity="page",
        timeout=timeout,
        polling=polling,
    )

to_have_url_changes

to_have_url_changes(url: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.current_url != url (URL has changed from the given value).

Source code in selenium_expect/assertions/driver.py
def to_have_url_changes(
    self,
    url: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.current_url != url (URL has changed from the given value)."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.current_url
        return (actual != url, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have URL changed from {url!r}",
        expected=f"!= {url!r}",
        entity="page",
        timeout=timeout,
        polling=polling,
    )

to_have_url_contains

to_have_url_contains(url: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert url in driver.current_url.

Source code in selenium_expect/assertions/driver.py
def to_have_url_contains(
    self,
    url: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert url in driver.current_url."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.current_url
        return (url in (actual or ""), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have URL containing {url!r}",
        expected=url,
        entity="page",
        timeout=timeout,
        polling=polling,
    )

to_have_url_matches

to_have_url_matches(pattern: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert re.search(pattern, driver.current_url).

Source code in selenium_expect/assertions/driver.py
def to_have_url_matches(
    self,
    pattern: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert re.search(pattern, driver.current_url)."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.current_url
        return (re.search(pattern, actual or "") is not None, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have URL matching {pattern!r}",
        expected=pattern,
        entity="page",
        timeout=timeout,
        polling=polling,
    )

to_have_window_count

to_have_window_count(count: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(driver.window_handles) == count.

Source code in selenium_expect/assertions/driver.py
def to_have_window_count(
    self,
    count: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(driver.window_handles) == count."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(driver.window_handles)
        return (actual == count, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have window count {count}",
        expected=count,
        entity="browser",
        timeout=timeout,
        polling=polling,
    )

to_have_window_count_greater_than

to_have_window_count_greater_than(n: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(driver.window_handles) > n.

Source code in selenium_expect/assertions/driver.py
def to_have_window_count_greater_than(
    self,
    n: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(driver.window_handles) > n."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(driver.window_handles)
        return (actual > n, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have window count > {n}",
        expected=f">{n}",
        entity="browser",
        timeout=timeout,
        polling=polling,
    )

to_have_window_count_less_than

to_have_window_count_less_than(n: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(driver.window_handles) < n.

Source code in selenium_expect/assertions/driver.py
def to_have_window_count_less_than(
    self,
    n: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(driver.window_handles) < n."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(driver.window_handles)
        return (actual < n, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have window count < {n}",
        expected=f"<{n}",
        entity="browser",
        timeout=timeout,
        polling=polling,
    )

to_have_window_handle

to_have_window_handle(handle: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.current_window_handle == handle.

Source code in selenium_expect/assertions/driver.py
def to_have_window_handle(
    self,
    handle: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.current_window_handle == handle."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.current_window_handle
        return (actual == handle, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have window handle {handle!r}",
        expected=handle,
        entity="browser",
        timeout=timeout,
        polling=polling,
    )

to_have_window_position

to_have_window_position(x: int, y: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.get_window_position() == {'x': x, 'y': y}.

Source code in selenium_expect/assertions/driver.py
def to_have_window_position(
    self,
    x: int,
    y: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.get_window_position() == {'x': x, 'y': y}."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        pos = driver.get_window_position()
        actual = {"x": pos["x"], "y": pos["y"]}
        return (actual == {"x": x, "y": y}, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have window position ({x}, {y})",
        expected={"x": x, "y": y},
        entity="browser",
        timeout=timeout,
        polling=polling,
    )

to_have_window_rect

to_have_window_rect(x: int, y: int, width: int, height: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.get_window_rect() matches all four values.

Source code in selenium_expect/assertions/driver.py
def to_have_window_rect(
    self,
    x: int,
    y: int,
    width: int,
    height: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.get_window_rect() matches all four values."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        rect = driver.get_window_rect()
        actual = {
            "x": rect["x"],
            "y": rect["y"],
            "width": rect["width"],
            "height": rect["height"],
        }
        expected = {"x": x, "y": y, "width": width, "height": height}
        return (actual == expected, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have window rect ({x}, {y}, {width}x{height})",
        expected={"x": x, "y": y, "width": width, "height": height},
        entity="browser",
        timeout=timeout,
        polling=polling,
    )

to_have_window_size

to_have_window_size(width: int, height: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.get_window_size() == {'width': width, 'height': height}.

Source code in selenium_expect/assertions/driver.py
def to_have_window_size(
    self,
    width: int,
    height: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.get_window_size() == {'width': width, 'height': height}."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        sz = driver.get_window_size()
        actual = {"width": sz["width"], "height": sz["height"]}
        return (actual == {"width": width, "height": height}, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have window size ({width}x{height})",
        expected={"width": width, "height": height},
        entity="browser",
        timeout=timeout,
        polling=polling,
    )

ExpectList

Assertions for lists of WebElement objects.

Key method categories:

  • Count: to_have_count, to_have_count_greater_than, to_have_count_less_than, to_have_count_greater_than_or_equal, to_have_count_less_than_or_equal, to_be_empty, to_be_not_empty
  • Text: to_have_texts, to_have_texts_contains, to_have_text_at, to_have_any_text, to_have_all_texts_contain, to_have_any_text_contain, to_have_none_text_contain, to_have_exact_texts, to_have_texts_containing, to_have_texts_in_any_order, to_have_first_text, to_have_last_text, to_have_nth_text_contains
  • Values: to_have_values, to_have_value_at
  • State: to_have_all_visible, to_have_any_visible, to_have_none_visible, to_have_all_enabled, to_have_all_selected
  • Attributes: to_have_attribute_at, to_have_all_attribute, to_have_any_attribute

selenium_expect.assertions.list.ExpectList

Bases: AssertionMixin

Assertions for lists of WebElements.

Source code in selenium_expect/assertions/list.py
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
class ExpectList(AssertionMixin):
    """Assertions for lists of WebElements."""

    def __init__(
        self,
        target: list[WebElement],
        config: ExpectConfig | None = None,
        message: str | None = None,
        negate: bool = False,
    ) -> None:
        super().__init__(target=target, config=config, message=message, negate=negate)

    # --- Count ---

    def to_have_count(
        self,
        count: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(elements) == count."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(elements)
            return (actual == count, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have count {count}",
            expected=count,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_count_greater_than(
        self,
        n: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(elements) > n."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(elements)
            return (actual > n, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have count > {n}",
            expected=f">{n}",
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_count_less_than(
        self,
        n: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(elements) < n."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(elements)
            return (actual < n, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have count < {n}",
            expected=f"<{n}",
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_count_greater_than_or_equal(
        self,
        n: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(elements) >= n."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(elements)
            return (actual >= n, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have count >= {n}",
            expected=f">={n}",
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_count_less_than_or_equal(
        self,
        n: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(elements) <= n."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(elements)
            return (actual <= n, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have count <= {n}",
            expected=f"<={n}",
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_be_empty(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(elements) == 0."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(elements)
            return (actual == 0, actual)

        self._run_assertion(
            condition=condition,
            condition_name="to be empty",
            expected=0,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_be_not_empty(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(elements) > 0."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(elements)
            return (actual > 0, actual)

        self._run_assertion(
            condition=condition,
            condition_name="to be not empty",
            expected=">0",
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    # --- Text ---

    def to_have_texts(
        self,
        texts: list[str],
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert [el.text for el in elements] == texts (exact, ordered)."""
        if not texts:
            raise ValueError("texts list must not be empty")
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = [el.text for el in elements]
            return (actual == texts, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have texts {texts!r}",
            expected=texts,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_texts_contains(
        self,
        texts: list[str],
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert each text in texts is in corresponding element.text."""
        if not texts:
            raise ValueError("texts list must not be empty")
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = [el.text for el in elements]
            if len(actual) != len(texts):
                return (False, actual)
            return (all(t in (a or "") for a, t in zip(actual, texts, strict=False)), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have texts containing {texts!r}",
            expected=texts,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_text_at(
        self,
        index: int,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert elements[index].text == text."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            if index >= len(elements) or index < -len(elements):
                return (False, f"index {index} out of range")
            actual = elements[index].text
            return (actual == text, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have text at [{index}]={text!r}",
            expected=text,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_any_text(
        self,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert any element has text == text."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = [el.text for el in elements]
            return (text in actual, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have any text {text!r}",
            expected=text,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_all_texts_contain(
        self,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert all elements contain text."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = [el.text for el in elements]
            return (all(text in (t or "") for t in actual) and len(actual) > 0, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have all texts containing {text!r}",
            expected=text,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_any_text_contain(
        self,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert any element contains text."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = [el.text for el in elements]
            return (any(text in (t or "") for t in actual), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have any text containing {text!r}",
            expected=text,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_none_text_contain(
        self,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert no element contains text."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = [el.text for el in elements]
            return (not any(text in (t or "") for t in actual) and len(actual) > 0, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have no text containing {text!r}",
            expected=f"none containing {text!r}",
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_exact_texts(
        self,
        *texts: str,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert [el.text for el in elements] == list(texts) (exact, ordered, varargs)."""
        if not texts:
            raise ValueError("At least one text must be provided")
        elements = self._target
        expected = list(texts)

        def condition() -> tuple[bool, Any]:
            actual = [el.text for el in elements]
            return (actual == expected, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have exact texts {expected!r}",
            expected=expected,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_texts_containing(
        self,
        *texts: str,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert each element.text contains the corresponding text (varargs)."""
        if not texts:
            raise ValueError("At least one text must be provided")
        elements = self._target
        expected = list(texts)

        def condition() -> tuple[bool, Any]:
            actual = [el.text for el in elements]
            if len(actual) != len(expected):
                return (False, actual)
            return (all(t in (a or "") for a, t in zip(actual, expected, strict=False)), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have texts containing {expected!r}",
            expected=expected,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_texts_in_any_order(
        self,
        *texts: str,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert element texts match texts in any order (varargs)."""
        if not texts:
            raise ValueError("At least one text must be provided")
        elements = self._target
        expected = sorted(texts)

        def condition() -> tuple[bool, Any]:
            actual = sorted(el.text for el in elements)
            return (actual == expected, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have texts in any order {list(texts)!r}",
            expected=list(texts),
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_first_text(
        self,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert elements[0].text == text."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            if not elements:
                return (False, "empty list")
            actual = elements[0].text
            return (actual == text, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have first text {text!r}",
            expected=text,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_last_text(
        self,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert elements[-1].text == text."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            if not elements:
                return (False, "empty list")
            actual = elements[-1].text
            return (actual == text, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have last text {text!r}",
            expected=text,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_nth_text_contains(
        self,
        index: int,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert text in elements[index].text."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            if index >= len(elements) or index < -len(elements):
                return (False, f"index {index} out of range")
            actual = elements[index].text
            return (text in (actual or ""), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have text at [{index}] containing {text!r}",
            expected=text,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    # --- Values ---

    def to_have_values(
        self,
        values: list[str],
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert [el.get_attribute('value') for el in elements] == values."""
        if not values:
            raise ValueError("values list must not be empty")
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = [el.get_attribute("value") for el in elements]
            return (actual == values, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have values {values!r}",
            expected=values,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_value_at(
        self,
        index: int,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert elements[index].get_attribute('value') == value."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            if index >= len(elements) or index < -len(elements):
                return (False, f"index {index} out of range")
            actual = elements[index].get_attribute("value")
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have value at [{index}]={value!r}",
            expected=value,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    # --- State (aggregate) ---

    def to_have_all_visible(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert all elements are visible."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = [el.is_displayed() for el in elements]
            return (all(actual) and len(actual) > 0, actual)

        self._run_assertion(
            condition=condition,
            condition_name="to have all visible",
            expected="all visible",
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_any_visible(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert at least one element is visible."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = [el.is_displayed() for el in elements]
            return (any(actual), actual)

        self._run_assertion(
            condition=condition,
            condition_name="to have any visible",
            expected="any visible",
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_none_visible(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert no element is visible."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = [el.is_displayed() for el in elements]
            return (not any(actual) and len(actual) > 0, actual)

        self._run_assertion(
            condition=condition,
            condition_name="to have none visible",
            expected="none visible",
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_all_enabled(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert all elements are enabled."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = [el.is_enabled() for el in elements]
            return (all(actual) and len(actual) > 0, actual)

        self._run_assertion(
            condition=condition,
            condition_name="to have all enabled",
            expected="all enabled",
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_all_selected(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert all elements are selected."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = [el.is_selected() for el in elements]
            return (all(actual) and len(actual) > 0, actual)

        self._run_assertion(
            condition=condition,
            condition_name="to have all selected",
            expected="all selected",
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    # --- Attributes ---

    def to_have_attribute_at(
        self,
        index: int,
        name: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert elements[index].get_attribute(name) == value."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            if index >= len(elements) or index < -len(elements):
                return (False, f"index {index} out of range")
            actual = elements[index].get_attribute(name)
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have attribute {name!r}={value!r} at [{index}]",
            expected=value,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_all_attribute(
        self,
        name: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert all elements have attribute == value."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = [el.get_attribute(name) for el in elements]
            return (all(a == value for a in actual) and len(actual) > 0, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have all attribute {name!r}={value!r}",
            expected=value,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    def to_have_any_attribute(
        self,
        name: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert any element has attribute == value."""
        elements = self._target

        def condition() -> tuple[bool, Any]:
            actual = [el.get_attribute(name) for el in elements]
            return (any(a == value for a in actual), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have any attribute {name!r}={value!r}",
            expected=value,
            entity="list",
            timeout=timeout,
            polling=polling,
        )

    # --- Overrides ---

    def _entity_description(self) -> str:
        return f"list[{len(self._target)}]"

    def _get_element_html(self) -> str | None:
        return None

to_be_empty

to_be_empty(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(elements) == 0.

Source code in selenium_expect/assertions/list.py
def to_be_empty(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(elements) == 0."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(elements)
        return (actual == 0, actual)

    self._run_assertion(
        condition=condition,
        condition_name="to be empty",
        expected=0,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_be_not_empty

to_be_not_empty(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(elements) > 0.

Source code in selenium_expect/assertions/list.py
def to_be_not_empty(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(elements) > 0."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(elements)
        return (actual > 0, actual)

    self._run_assertion(
        condition=condition,
        condition_name="to be not empty",
        expected=">0",
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_all_attribute

to_have_all_attribute(name: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert all elements have attribute == value.

Source code in selenium_expect/assertions/list.py
def to_have_all_attribute(
    self,
    name: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert all elements have attribute == value."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = [el.get_attribute(name) for el in elements]
        return (all(a == value for a in actual) and len(actual) > 0, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have all attribute {name!r}={value!r}",
        expected=value,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_all_enabled

to_have_all_enabled(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert all elements are enabled.

Source code in selenium_expect/assertions/list.py
def to_have_all_enabled(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert all elements are enabled."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = [el.is_enabled() for el in elements]
        return (all(actual) and len(actual) > 0, actual)

    self._run_assertion(
        condition=condition,
        condition_name="to have all enabled",
        expected="all enabled",
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_all_selected

to_have_all_selected(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert all elements are selected.

Source code in selenium_expect/assertions/list.py
def to_have_all_selected(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert all elements are selected."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = [el.is_selected() for el in elements]
        return (all(actual) and len(actual) > 0, actual)

    self._run_assertion(
        condition=condition,
        condition_name="to have all selected",
        expected="all selected",
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_all_texts_contain

to_have_all_texts_contain(text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert all elements contain text.

Source code in selenium_expect/assertions/list.py
def to_have_all_texts_contain(
    self,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert all elements contain text."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = [el.text for el in elements]
        return (all(text in (t or "") for t in actual) and len(actual) > 0, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have all texts containing {text!r}",
        expected=text,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_all_visible

to_have_all_visible(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert all elements are visible.

Source code in selenium_expect/assertions/list.py
def to_have_all_visible(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert all elements are visible."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = [el.is_displayed() for el in elements]
        return (all(actual) and len(actual) > 0, actual)

    self._run_assertion(
        condition=condition,
        condition_name="to have all visible",
        expected="all visible",
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_any_attribute

to_have_any_attribute(name: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert any element has attribute == value.

Source code in selenium_expect/assertions/list.py
def to_have_any_attribute(
    self,
    name: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert any element has attribute == value."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = [el.get_attribute(name) for el in elements]
        return (any(a == value for a in actual), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have any attribute {name!r}={value!r}",
        expected=value,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_any_text

to_have_any_text(text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert any element has text == text.

Source code in selenium_expect/assertions/list.py
def to_have_any_text(
    self,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert any element has text == text."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = [el.text for el in elements]
        return (text in actual, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have any text {text!r}",
        expected=text,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_any_text_contain

to_have_any_text_contain(text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert any element contains text.

Source code in selenium_expect/assertions/list.py
def to_have_any_text_contain(
    self,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert any element contains text."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = [el.text for el in elements]
        return (any(text in (t or "") for t in actual), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have any text containing {text!r}",
        expected=text,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_any_visible

to_have_any_visible(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert at least one element is visible.

Source code in selenium_expect/assertions/list.py
def to_have_any_visible(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert at least one element is visible."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = [el.is_displayed() for el in elements]
        return (any(actual), actual)

    self._run_assertion(
        condition=condition,
        condition_name="to have any visible",
        expected="any visible",
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_attribute_at

to_have_attribute_at(index: int, name: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert elements[index].get_attribute(name) == value.

Source code in selenium_expect/assertions/list.py
def to_have_attribute_at(
    self,
    index: int,
    name: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert elements[index].get_attribute(name) == value."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        if index >= len(elements) or index < -len(elements):
            return (False, f"index {index} out of range")
        actual = elements[index].get_attribute(name)
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have attribute {name!r}={value!r} at [{index}]",
        expected=value,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_count

to_have_count(count: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(elements) == count.

Source code in selenium_expect/assertions/list.py
def to_have_count(
    self,
    count: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(elements) == count."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(elements)
        return (actual == count, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have count {count}",
        expected=count,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_count_greater_than

to_have_count_greater_than(n: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(elements) > n.

Source code in selenium_expect/assertions/list.py
def to_have_count_greater_than(
    self,
    n: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(elements) > n."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(elements)
        return (actual > n, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have count > {n}",
        expected=f">{n}",
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_count_greater_than_or_equal

to_have_count_greater_than_or_equal(n: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(elements) >= n.

Source code in selenium_expect/assertions/list.py
def to_have_count_greater_than_or_equal(
    self,
    n: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(elements) >= n."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(elements)
        return (actual >= n, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have count >= {n}",
        expected=f">={n}",
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_count_less_than

to_have_count_less_than(n: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(elements) < n.

Source code in selenium_expect/assertions/list.py
def to_have_count_less_than(
    self,
    n: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(elements) < n."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(elements)
        return (actual < n, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have count < {n}",
        expected=f"<{n}",
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_count_less_than_or_equal

to_have_count_less_than_or_equal(n: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(elements) <= n.

Source code in selenium_expect/assertions/list.py
def to_have_count_less_than_or_equal(
    self,
    n: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(elements) <= n."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(elements)
        return (actual <= n, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have count <= {n}",
        expected=f"<={n}",
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_exact_texts

to_have_exact_texts(*texts: str, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert [el.text for el in elements] == list(texts) (exact, ordered, varargs).

Source code in selenium_expect/assertions/list.py
def to_have_exact_texts(
    self,
    *texts: str,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert [el.text for el in elements] == list(texts) (exact, ordered, varargs)."""
    if not texts:
        raise ValueError("At least one text must be provided")
    elements = self._target
    expected = list(texts)

    def condition() -> tuple[bool, Any]:
        actual = [el.text for el in elements]
        return (actual == expected, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have exact texts {expected!r}",
        expected=expected,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_first_text

to_have_first_text(text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert elements[0].text == text.

Source code in selenium_expect/assertions/list.py
def to_have_first_text(
    self,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert elements[0].text == text."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        if not elements:
            return (False, "empty list")
        actual = elements[0].text
        return (actual == text, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have first text {text!r}",
        expected=text,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_last_text

to_have_last_text(text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert elements[-1].text == text.

Source code in selenium_expect/assertions/list.py
def to_have_last_text(
    self,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert elements[-1].text == text."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        if not elements:
            return (False, "empty list")
        actual = elements[-1].text
        return (actual == text, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have last text {text!r}",
        expected=text,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_none_text_contain

to_have_none_text_contain(text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert no element contains text.

Source code in selenium_expect/assertions/list.py
def to_have_none_text_contain(
    self,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert no element contains text."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = [el.text for el in elements]
        return (not any(text in (t or "") for t in actual) and len(actual) > 0, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have no text containing {text!r}",
        expected=f"none containing {text!r}",
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_none_visible

to_have_none_visible(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert no element is visible.

Source code in selenium_expect/assertions/list.py
def to_have_none_visible(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert no element is visible."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = [el.is_displayed() for el in elements]
        return (not any(actual) and len(actual) > 0, actual)

    self._run_assertion(
        condition=condition,
        condition_name="to have none visible",
        expected="none visible",
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_nth_text_contains

to_have_nth_text_contains(index: int, text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert text in elements[index].text.

Source code in selenium_expect/assertions/list.py
def to_have_nth_text_contains(
    self,
    index: int,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert text in elements[index].text."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        if index >= len(elements) or index < -len(elements):
            return (False, f"index {index} out of range")
        actual = elements[index].text
        return (text in (actual or ""), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have text at [{index}] containing {text!r}",
        expected=text,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_text_at

to_have_text_at(index: int, text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert elements[index].text == text.

Source code in selenium_expect/assertions/list.py
def to_have_text_at(
    self,
    index: int,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert elements[index].text == text."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        if index >= len(elements) or index < -len(elements):
            return (False, f"index {index} out of range")
        actual = elements[index].text
        return (actual == text, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have text at [{index}]={text!r}",
        expected=text,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_texts

to_have_texts(texts: list[str], *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert [el.text for el in elements] == texts (exact, ordered).

Source code in selenium_expect/assertions/list.py
def to_have_texts(
    self,
    texts: list[str],
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert [el.text for el in elements] == texts (exact, ordered)."""
    if not texts:
        raise ValueError("texts list must not be empty")
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = [el.text for el in elements]
        return (actual == texts, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have texts {texts!r}",
        expected=texts,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_texts_containing

to_have_texts_containing(*texts: str, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert each element.text contains the corresponding text (varargs).

Source code in selenium_expect/assertions/list.py
def to_have_texts_containing(
    self,
    *texts: str,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert each element.text contains the corresponding text (varargs)."""
    if not texts:
        raise ValueError("At least one text must be provided")
    elements = self._target
    expected = list(texts)

    def condition() -> tuple[bool, Any]:
        actual = [el.text for el in elements]
        if len(actual) != len(expected):
            return (False, actual)
        return (all(t in (a or "") for a, t in zip(actual, expected, strict=False)), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have texts containing {expected!r}",
        expected=expected,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_texts_contains

to_have_texts_contains(texts: list[str], *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert each text in texts is in corresponding element.text.

Source code in selenium_expect/assertions/list.py
def to_have_texts_contains(
    self,
    texts: list[str],
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert each text in texts is in corresponding element.text."""
    if not texts:
        raise ValueError("texts list must not be empty")
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = [el.text for el in elements]
        if len(actual) != len(texts):
            return (False, actual)
        return (all(t in (a or "") for a, t in zip(actual, texts, strict=False)), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have texts containing {texts!r}",
        expected=texts,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_texts_in_any_order

to_have_texts_in_any_order(*texts: str, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert element texts match texts in any order (varargs).

Source code in selenium_expect/assertions/list.py
def to_have_texts_in_any_order(
    self,
    *texts: str,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert element texts match texts in any order (varargs)."""
    if not texts:
        raise ValueError("At least one text must be provided")
    elements = self._target
    expected = sorted(texts)

    def condition() -> tuple[bool, Any]:
        actual = sorted(el.text for el in elements)
        return (actual == expected, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have texts in any order {list(texts)!r}",
        expected=list(texts),
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_value_at

to_have_value_at(index: int, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert elements[index].get_attribute('value') == value.

Source code in selenium_expect/assertions/list.py
def to_have_value_at(
    self,
    index: int,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert elements[index].get_attribute('value') == value."""
    elements = self._target

    def condition() -> tuple[bool, Any]:
        if index >= len(elements) or index < -len(elements):
            return (False, f"index {index} out of range")
        actual = elements[index].get_attribute("value")
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have value at [{index}]={value!r}",
        expected=value,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

to_have_values

to_have_values(values: list[str], *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert [el.get_attribute('value') for el in elements] == values.

Source code in selenium_expect/assertions/list.py
def to_have_values(
    self,
    values: list[str],
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert [el.get_attribute('value') for el in elements] == values."""
    if not values:
        raise ValueError("values list must not be empty")
    elements = self._target

    def condition() -> tuple[bool, Any]:
        actual = [el.get_attribute("value") for el in elements]
        return (actual == values, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have values {values!r}",
        expected=values,
        entity="list",
        timeout=timeout,
        polling=polling,
    )

ExpectAlert

Assertions for JavaScript Alert objects.

Methods: to_be_present, to_have_text, to_have_text_contains, to_have_text_matches

selenium_expect.assertions.alert.ExpectAlert

Bases: AssertionMixin

Assertions for JavaScript alerts/confirms/prompts.

Source code in selenium_expect/assertions/alert.py
class ExpectAlert(AssertionMixin):
    """Assertions for JavaScript alerts/confirms/prompts."""

    def __init__(
        self,
        target: Alert,
        config: ExpectConfig | None = None,
        message: str | None = None,
        negate: bool = False,
    ) -> None:
        super().__init__(target=target, config=config, message=message, negate=negate)

    def to_be_present(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert alert is present (accessing .text doesn't raise)."""
        alert = self._target

        def condition() -> tuple[bool, Any]:
            try:
                _ = alert.text
                return (True, "present")
            except NoAlertPresentException:
                return (False, "not present")

        self._run_assertion(
            condition=condition,
            condition_name="to be present",
            expected="present",
            entity="alert",
            timeout=timeout,
            polling=polling,
        )

    def to_have_text(
        self,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert alert.text == text."""
        alert = self._target

        def condition() -> tuple[bool, Any]:
            actual = alert.text
            return (actual == text, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have text {text!r}",
            expected=text,
            entity="alert",
            timeout=timeout,
            polling=polling,
        )

    def to_have_text_contains(
        self,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert text in alert.text."""
        alert = self._target

        def condition() -> tuple[bool, Any]:
            actual = alert.text
            return (text in (actual or ""), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have text containing {text!r}",
            expected=text,
            entity="alert",
            timeout=timeout,
            polling=polling,
        )

    def to_have_text_matches(
        self,
        pattern: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert re.search(pattern, alert.text)."""
        alert = self._target

        def condition() -> tuple[bool, Any]:
            actual = alert.text
            return (re.search(pattern, actual or "") is not None, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have text matching {pattern!r}",
            expected=pattern,
            entity="alert",
            timeout=timeout,
            polling=polling,
        )

    # --- Overrides ---

    def _entity_description(self) -> str:
        return "Alert"

    def _get_element_html(self) -> str | None:
        return None

to_be_present

to_be_present(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert alert is present (accessing .text doesn't raise).

Source code in selenium_expect/assertions/alert.py
def to_be_present(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert alert is present (accessing .text doesn't raise)."""
    alert = self._target

    def condition() -> tuple[bool, Any]:
        try:
            _ = alert.text
            return (True, "present")
        except NoAlertPresentException:
            return (False, "not present")

    self._run_assertion(
        condition=condition,
        condition_name="to be present",
        expected="present",
        entity="alert",
        timeout=timeout,
        polling=polling,
    )

to_have_text

to_have_text(text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert alert.text == text.

Source code in selenium_expect/assertions/alert.py
def to_have_text(
    self,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert alert.text == text."""
    alert = self._target

    def condition() -> tuple[bool, Any]:
        actual = alert.text
        return (actual == text, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have text {text!r}",
        expected=text,
        entity="alert",
        timeout=timeout,
        polling=polling,
    )

to_have_text_contains

to_have_text_contains(text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert text in alert.text.

Source code in selenium_expect/assertions/alert.py
def to_have_text_contains(
    self,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert text in alert.text."""
    alert = self._target

    def condition() -> tuple[bool, Any]:
        actual = alert.text
        return (text in (actual or ""), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have text containing {text!r}",
        expected=text,
        entity="alert",
        timeout=timeout,
        polling=polling,
    )

to_have_text_matches

to_have_text_matches(pattern: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert re.search(pattern, alert.text).

Source code in selenium_expect/assertions/alert.py
def to_have_text_matches(
    self,
    pattern: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert re.search(pattern, alert.text)."""
    alert = self._target

    def condition() -> tuple[bool, Any]:
        actual = alert.text
        return (re.search(pattern, actual or "") is not None, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have text matching {pattern!r}",
        expected=pattern,
        entity="alert",
        timeout=timeout,
        polling=polling,
    )

ExpectCookie

Assertions for browser cookies.

Key method categories:

  • Presence: to_have_cookie, to_have_no_cookies, to_have_cookie_count, to_have_cookie_count_greater_than
  • Value: to_have_cookie_value, to_have_cookie_domain, to_have_cookie_path, to_have_cookie_expiry
  • Security: to_have_cookie_secure, to_have_cookie_http_only, to_have_cookie_same_site

selenium_expect.assertions.cookie.ExpectCookie

Bases: AssertionMixin

Assertions for browser cookies.

Initialized with a WebDriver — uses driver.get_cookie() and driver.get_cookies() to inspect cookies. Not dispatched via expect() (which maps WebDriver to ExpectDriver); instantiate directly or via a helper.

Source code in selenium_expect/assertions/cookie.py
class ExpectCookie(AssertionMixin):
    """Assertions for browser cookies.

    Initialized with a ``WebDriver`` — uses ``driver.get_cookie()`` and
    ``driver.get_cookies()`` to inspect cookies.  Not dispatched via
    ``expect()`` (which maps ``WebDriver`` to ``ExpectDriver``); instantiate
    directly or via a helper.
    """

    def __init__(
        self,
        target: WebDriver,
        config: ExpectConfig | None = None,
        message: str | None = None,
        negate: bool = False,
    ) -> None:
        super().__init__(target=target, config=config, message=message, negate=negate)

    # --- Cookie presence ---

    def to_have_cookie(
        self,
        name: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.get_cookie(name) is not None."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            cookie = driver.get_cookie(name)
            return (cookie is not None, cookie)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have cookie {name!r}",
            expected=name,
            entity="cookies",
            timeout=timeout,
            polling=polling,
        )

    def to_have_cookie_value(
        self,
        name: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.get_cookie(name)['value'] == value."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            cookie = driver.get_cookie(name)
            actual = cookie.get("value") if cookie else None
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have cookie {name!r} value {value!r}",
            expected=value,
            entity="cookies",
            timeout=timeout,
            polling=polling,
        )

    def to_have_cookie_value_contains(
        self,
        name: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert value in driver.get_cookie(name)['value']."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            cookie = driver.get_cookie(name)
            actual = cookie.get("value") if cookie else None
            return (value in (actual or ""), actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have cookie {name!r} value containing {value!r}",
            expected=value,
            entity="cookies",
            timeout=timeout,
            polling=polling,
        )

    def to_have_cookie_domain(
        self,
        name: str,
        domain: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.get_cookie(name)['domain'] == domain."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            cookie = driver.get_cookie(name)
            actual = cookie.get("domain") if cookie else None
            return (actual == domain, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have cookie {name!r} domain {domain!r}",
            expected=domain,
            entity="cookies",
            timeout=timeout,
            polling=polling,
        )

    def to_have_cookie_path(
        self,
        name: str,
        path: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.get_cookie(name)['path'] == path."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            cookie = driver.get_cookie(name)
            actual = cookie.get("path") if cookie else None
            return (actual == path, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have cookie {name!r} path {path!r}",
            expected=path,
            entity="cookies",
            timeout=timeout,
            polling=polling,
        )

    def to_have_cookie_http_only(
        self,
        name: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.get_cookie(name)['httpOnly'] == True."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            cookie = driver.get_cookie(name)
            actual = cookie.get("httpOnly") if cookie else None
            return (actual is True, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have cookie {name!r} httpOnly=True",
            expected=True,
            entity="cookies",
            timeout=timeout,
            polling=polling,
        )

    def to_have_cookie_secure(
        self,
        name: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.get_cookie(name)['secure'] == True."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            cookie = driver.get_cookie(name)
            actual = cookie.get("secure") if cookie else None
            return (actual is True, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have cookie {name!r} secure=True",
            expected=True,
            entity="cookies",
            timeout=timeout,
            polling=polling,
        )

    def to_have_cookie_same_site(
        self,
        name: str,
        same_site: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.get_cookie(name)['sameSite'] == same_site."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            cookie = driver.get_cookie(name)
            actual = cookie.get("sameSite") if cookie else None
            return (actual == same_site, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have cookie {name!r} sameSite={same_site!r}",
            expected=same_site,
            entity="cookies",
            timeout=timeout,
            polling=polling,
        )

    def to_have_cookie_count(
        self,
        count: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(driver.get_cookies()) == count."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(driver.get_cookies())
            return (actual == count, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have cookie count {count}",
            expected=count,
            entity="cookies",
            timeout=timeout,
            polling=polling,
        )

    def to_have_cookie_count_greater_than(
        self,
        n: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(driver.get_cookies()) > n."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(driver.get_cookies())
            return (actual > n, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have cookie count > {n}",
            expected=f">{n}",
            entity="cookies",
            timeout=timeout,
            polling=polling,
        )

    def to_have_cookie_expiry(
        self,
        name: str,
        expiry: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.get_cookie(name)['expiry'] == expiry."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            cookie = driver.get_cookie(name)
            if cookie is None:
                return (False, "cookie not found")
            actual = cookie.get("expiry")
            return (actual == expiry, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have cookie {name!r} expiry {expiry}",
            expected=expiry,
            entity="cookies",
            timeout=timeout,
            polling=polling,
        )

    def to_have_no_cookies(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(driver.get_cookies()) == 0."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(driver.get_cookies())
            return (actual == 0, actual)

        self._run_assertion(
            condition=condition,
            condition_name="to have no cookies",
            expected=0,
            entity="cookies",
            timeout=timeout,
            polling=polling,
        )

    # --- Overrides ---

    def _entity_description(self) -> str:
        return "cookies"

    def _get_element_html(self) -> str | None:
        return None
to_have_cookie(name: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.get_cookie(name) is not None.

Source code in selenium_expect/assertions/cookie.py
def to_have_cookie(
    self,
    name: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.get_cookie(name) is not None."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        cookie = driver.get_cookie(name)
        return (cookie is not None, cookie)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have cookie {name!r}",
        expected=name,
        entity="cookies",
        timeout=timeout,
        polling=polling,
    )
to_have_cookie_count(count: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(driver.get_cookies()) == count.

Source code in selenium_expect/assertions/cookie.py
def to_have_cookie_count(
    self,
    count: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(driver.get_cookies()) == count."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(driver.get_cookies())
        return (actual == count, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have cookie count {count}",
        expected=count,
        entity="cookies",
        timeout=timeout,
        polling=polling,
    )
to_have_cookie_count_greater_than(n: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(driver.get_cookies()) > n.

Source code in selenium_expect/assertions/cookie.py
def to_have_cookie_count_greater_than(
    self,
    n: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(driver.get_cookies()) > n."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(driver.get_cookies())
        return (actual > n, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have cookie count > {n}",
        expected=f">{n}",
        entity="cookies",
        timeout=timeout,
        polling=polling,
    )
to_have_cookie_domain(name: str, domain: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.get_cookie(name)['domain'] == domain.

Source code in selenium_expect/assertions/cookie.py
def to_have_cookie_domain(
    self,
    name: str,
    domain: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.get_cookie(name)['domain'] == domain."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        cookie = driver.get_cookie(name)
        actual = cookie.get("domain") if cookie else None
        return (actual == domain, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have cookie {name!r} domain {domain!r}",
        expected=domain,
        entity="cookies",
        timeout=timeout,
        polling=polling,
    )
to_have_cookie_expiry(name: str, expiry: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.get_cookie(name)['expiry'] == expiry.

Source code in selenium_expect/assertions/cookie.py
def to_have_cookie_expiry(
    self,
    name: str,
    expiry: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.get_cookie(name)['expiry'] == expiry."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        cookie = driver.get_cookie(name)
        if cookie is None:
            return (False, "cookie not found")
        actual = cookie.get("expiry")
        return (actual == expiry, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have cookie {name!r} expiry {expiry}",
        expected=expiry,
        entity="cookies",
        timeout=timeout,
        polling=polling,
    )
to_have_cookie_http_only(name: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.get_cookie(name)['httpOnly'] == True.

Source code in selenium_expect/assertions/cookie.py
def to_have_cookie_http_only(
    self,
    name: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.get_cookie(name)['httpOnly'] == True."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        cookie = driver.get_cookie(name)
        actual = cookie.get("httpOnly") if cookie else None
        return (actual is True, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have cookie {name!r} httpOnly=True",
        expected=True,
        entity="cookies",
        timeout=timeout,
        polling=polling,
    )
to_have_cookie_path(name: str, path: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.get_cookie(name)['path'] == path.

Source code in selenium_expect/assertions/cookie.py
def to_have_cookie_path(
    self,
    name: str,
    path: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.get_cookie(name)['path'] == path."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        cookie = driver.get_cookie(name)
        actual = cookie.get("path") if cookie else None
        return (actual == path, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have cookie {name!r} path {path!r}",
        expected=path,
        entity="cookies",
        timeout=timeout,
        polling=polling,
    )
to_have_cookie_same_site(name: str, same_site: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.get_cookie(name)['sameSite'] == same_site.

Source code in selenium_expect/assertions/cookie.py
def to_have_cookie_same_site(
    self,
    name: str,
    same_site: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.get_cookie(name)['sameSite'] == same_site."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        cookie = driver.get_cookie(name)
        actual = cookie.get("sameSite") if cookie else None
        return (actual == same_site, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have cookie {name!r} sameSite={same_site!r}",
        expected=same_site,
        entity="cookies",
        timeout=timeout,
        polling=polling,
    )
to_have_cookie_secure(name: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.get_cookie(name)['secure'] == True.

Source code in selenium_expect/assertions/cookie.py
def to_have_cookie_secure(
    self,
    name: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.get_cookie(name)['secure'] == True."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        cookie = driver.get_cookie(name)
        actual = cookie.get("secure") if cookie else None
        return (actual is True, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have cookie {name!r} secure=True",
        expected=True,
        entity="cookies",
        timeout=timeout,
        polling=polling,
    )
to_have_cookie_value(name: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.get_cookie(name)['value'] == value.

Source code in selenium_expect/assertions/cookie.py
def to_have_cookie_value(
    self,
    name: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.get_cookie(name)['value'] == value."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        cookie = driver.get_cookie(name)
        actual = cookie.get("value") if cookie else None
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have cookie {name!r} value {value!r}",
        expected=value,
        entity="cookies",
        timeout=timeout,
        polling=polling,
    )
to_have_cookie_value_contains(name: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert value in driver.get_cookie(name)['value'].

Source code in selenium_expect/assertions/cookie.py
def to_have_cookie_value_contains(
    self,
    name: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert value in driver.get_cookie(name)['value']."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        cookie = driver.get_cookie(name)
        actual = cookie.get("value") if cookie else None
        return (value in (actual or ""), actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have cookie {name!r} value containing {value!r}",
        expected=value,
        entity="cookies",
        timeout=timeout,
        polling=polling,
    )

to_have_no_cookies

to_have_no_cookies(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(driver.get_cookies()) == 0.

Source code in selenium_expect/assertions/cookie.py
def to_have_no_cookies(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(driver.get_cookies()) == 0."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(driver.get_cookies())
        return (actual == 0, actual)

    self._run_assertion(
        condition=condition,
        condition_name="to have no cookies",
        expected=0,
        entity="cookies",
        timeout=timeout,
        polling=polling,
    )

ExpectSelect

Assertions for HTML <select> elements.

Key method categories:

  • Selection: to_have_value, to_have_first_selected_value, to_have_selected_text, to_have_selected_index, to_have_selected_values, to_have_selected_texts, to_have_selected_count, to_have_no_selection
  • Options: to_have_option_count, to_have_option_count_greater_than, to_have_option, to_have_option_text, to_have_option_at_index
  • Type: to_be_multiple, to_be_single_select

selenium_expect.assertions.select.ExpectSelect

Bases: AssertionMixin

Assertions for Select/dropdown elements.

Source code in selenium_expect/assertions/select.py
class ExpectSelect(AssertionMixin):
    """Assertions for Select/dropdown elements."""

    def __init__(
        self,
        target: Select,
        config: ExpectConfig | None = None,
        message: str | None = None,
        negate: bool = False,
    ) -> None:
        super().__init__(target=target, config=config, message=message, negate=negate)

    def to_have_value(
        self,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert select.first_selected_option.get_attribute('value') == value."""
        select = self._target

        def condition() -> tuple[bool, Any]:
            actual = select.first_selected_option.get_attribute("value")
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have value {value!r}",
            expected=value,
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    def to_have_first_selected_value(
        self,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert select.first_selected_option.get_attribute('value') == value (alias)."""
        select = self._target

        def condition() -> tuple[bool, Any]:
            actual = select.first_selected_option.get_attribute("value")
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have first selected value {value!r}",
            expected=value,
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    def to_have_selected_text(
        self,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert select.first_selected_option.text == text."""
        select = self._target

        def condition() -> tuple[bool, Any]:
            actual = select.first_selected_option.text
            return (actual == text, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have selected text {text!r}",
            expected=text,
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    def to_have_selected_values(
        self,
        values: list[str],
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert [opt.get_attribute('value') for opt in all_selected_options] == values."""
        if not values:
            raise ValueError("values list must not be empty")
        select = self._target

        def condition() -> tuple[bool, Any]:
            actual = [opt.get_attribute("value") for opt in select.all_selected_options]
            return (actual == values, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have selected values {values!r}",
            expected=values,
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    def to_have_selected_texts(
        self,
        texts: list[str],
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert [opt.text for opt in all_selected_options] == texts."""
        if not texts:
            raise ValueError("texts list must not be empty")
        select = self._target

        def condition() -> tuple[bool, Any]:
            actual = [opt.text for opt in select.all_selected_options]
            return (actual == texts, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have selected texts {texts!r}",
            expected=texts,
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    def to_have_selected_count(
        self,
        count: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(select.all_selected_options) == count."""
        select = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(select.all_selected_options)
            return (actual == count, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have selected count {count}",
            expected=count,
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    def to_have_option_count(
        self,
        count: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(select.options) == count."""
        select = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(select.options)
            return (actual == count, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have option count {count}",
            expected=count,
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    def to_have_option_count_greater_than(
        self,
        n: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(select.options) > n."""
        select = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(select.options)
            return (actual > n, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have option count > {n}",
            expected=f">{n}",
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    def to_have_option_at_index(
        self,
        index: int,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert select.options[index].text == text."""
        select = self._target

        def condition() -> tuple[bool, Any]:
            if index >= len(select.options) or index < -len(select.options):
                return (False, f"index {index} out of range")
            actual = select.options[index].text
            return (actual == text, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have option at [{index}]={text!r}",
            expected=text,
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    def to_have_option(
        self,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert value exists in select options (by value attribute)."""
        select = self._target

        def condition() -> tuple[bool, Any]:
            actual = [opt.get_attribute("value") for opt in select.options]
            return (value in actual, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have option with value {value!r}",
            expected=value,
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    def to_have_option_text(
        self,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert text exists in select options (by visible text)."""
        select = self._target

        def condition() -> tuple[bool, Any]:
            actual = [opt.text for opt in select.options]
            return (text in actual, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have option with text {text!r}",
            expected=text,
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    def to_be_multiple(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert select.is_multiple == True."""
        select = self._target

        def condition() -> tuple[bool, Any]:
            actual = select.is_multiple
            return (actual is True, actual)

        self._run_assertion(
            condition=condition,
            condition_name="to be multiple",
            expected=True,
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    def to_be_single_select(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert select.is_multiple == False."""
        select = self._target

        def condition() -> tuple[bool, Any]:
            actual = select.is_multiple
            return (actual is False, actual)

        self._run_assertion(
            condition=condition,
            condition_name="to be single select",
            expected=False,
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    def to_have_selected_index(
        self,
        index: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert select.options[index].is_selected() == True."""
        select = self._target

        def condition() -> tuple[bool, Any]:
            if index >= len(select.options) or index < -len(select.options):
                return (False, f"index {index} out of range")
            actual = select.options[index].is_selected()
            return (actual is True, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have selected index {index}",
            expected=True,
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    def to_have_no_selection(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert select.all_selected_options is empty."""
        select = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(select.all_selected_options)
            return (actual == 0, actual)

        self._run_assertion(
            condition=condition,
            condition_name="to have no selection",
            expected=0,
            entity="select",
            timeout=timeout,
            polling=polling,
        )

    # --- Overrides ---

    def _entity_description(self) -> str:
        return "Select"

    def _get_element_html(self) -> str | None:
        return None

to_be_multiple

to_be_multiple(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert select.is_multiple == True.

Source code in selenium_expect/assertions/select.py
def to_be_multiple(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert select.is_multiple == True."""
    select = self._target

    def condition() -> tuple[bool, Any]:
        actual = select.is_multiple
        return (actual is True, actual)

    self._run_assertion(
        condition=condition,
        condition_name="to be multiple",
        expected=True,
        entity="select",
        timeout=timeout,
        polling=polling,
    )

to_be_single_select

to_be_single_select(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert select.is_multiple == False.

Source code in selenium_expect/assertions/select.py
def to_be_single_select(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert select.is_multiple == False."""
    select = self._target

    def condition() -> tuple[bool, Any]:
        actual = select.is_multiple
        return (actual is False, actual)

    self._run_assertion(
        condition=condition,
        condition_name="to be single select",
        expected=False,
        entity="select",
        timeout=timeout,
        polling=polling,
    )

to_have_first_selected_value

to_have_first_selected_value(value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert select.first_selected_option.get_attribute('value') == value (alias).

Source code in selenium_expect/assertions/select.py
def to_have_first_selected_value(
    self,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert select.first_selected_option.get_attribute('value') == value (alias)."""
    select = self._target

    def condition() -> tuple[bool, Any]:
        actual = select.first_selected_option.get_attribute("value")
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have first selected value {value!r}",
        expected=value,
        entity="select",
        timeout=timeout,
        polling=polling,
    )

to_have_no_selection

to_have_no_selection(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert select.all_selected_options is empty.

Source code in selenium_expect/assertions/select.py
def to_have_no_selection(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert select.all_selected_options is empty."""
    select = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(select.all_selected_options)
        return (actual == 0, actual)

    self._run_assertion(
        condition=condition,
        condition_name="to have no selection",
        expected=0,
        entity="select",
        timeout=timeout,
        polling=polling,
    )

to_have_option

to_have_option(value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert value exists in select options (by value attribute).

Source code in selenium_expect/assertions/select.py
def to_have_option(
    self,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert value exists in select options (by value attribute)."""
    select = self._target

    def condition() -> tuple[bool, Any]:
        actual = [opt.get_attribute("value") for opt in select.options]
        return (value in actual, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have option with value {value!r}",
        expected=value,
        entity="select",
        timeout=timeout,
        polling=polling,
    )

to_have_option_at_index

to_have_option_at_index(index: int, text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert select.options[index].text == text.

Source code in selenium_expect/assertions/select.py
def to_have_option_at_index(
    self,
    index: int,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert select.options[index].text == text."""
    select = self._target

    def condition() -> tuple[bool, Any]:
        if index >= len(select.options) or index < -len(select.options):
            return (False, f"index {index} out of range")
        actual = select.options[index].text
        return (actual == text, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have option at [{index}]={text!r}",
        expected=text,
        entity="select",
        timeout=timeout,
        polling=polling,
    )

to_have_option_count

to_have_option_count(count: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(select.options) == count.

Source code in selenium_expect/assertions/select.py
def to_have_option_count(
    self,
    count: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(select.options) == count."""
    select = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(select.options)
        return (actual == count, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have option count {count}",
        expected=count,
        entity="select",
        timeout=timeout,
        polling=polling,
    )

to_have_option_count_greater_than

to_have_option_count_greater_than(n: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(select.options) > n.

Source code in selenium_expect/assertions/select.py
def to_have_option_count_greater_than(
    self,
    n: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(select.options) > n."""
    select = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(select.options)
        return (actual > n, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have option count > {n}",
        expected=f">{n}",
        entity="select",
        timeout=timeout,
        polling=polling,
    )

to_have_option_text

to_have_option_text(text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert text exists in select options (by visible text).

Source code in selenium_expect/assertions/select.py
def to_have_option_text(
    self,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert text exists in select options (by visible text)."""
    select = self._target

    def condition() -> tuple[bool, Any]:
        actual = [opt.text for opt in select.options]
        return (text in actual, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have option with text {text!r}",
        expected=text,
        entity="select",
        timeout=timeout,
        polling=polling,
    )

to_have_selected_count

to_have_selected_count(count: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(select.all_selected_options) == count.

Source code in selenium_expect/assertions/select.py
def to_have_selected_count(
    self,
    count: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(select.all_selected_options) == count."""
    select = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(select.all_selected_options)
        return (actual == count, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have selected count {count}",
        expected=count,
        entity="select",
        timeout=timeout,
        polling=polling,
    )

to_have_selected_index

to_have_selected_index(index: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert select.options[index].is_selected() == True.

Source code in selenium_expect/assertions/select.py
def to_have_selected_index(
    self,
    index: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert select.options[index].is_selected() == True."""
    select = self._target

    def condition() -> tuple[bool, Any]:
        if index >= len(select.options) or index < -len(select.options):
            return (False, f"index {index} out of range")
        actual = select.options[index].is_selected()
        return (actual is True, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have selected index {index}",
        expected=True,
        entity="select",
        timeout=timeout,
        polling=polling,
    )

to_have_selected_text

to_have_selected_text(text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert select.first_selected_option.text == text.

Source code in selenium_expect/assertions/select.py
def to_have_selected_text(
    self,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert select.first_selected_option.text == text."""
    select = self._target

    def condition() -> tuple[bool, Any]:
        actual = select.first_selected_option.text
        return (actual == text, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have selected text {text!r}",
        expected=text,
        entity="select",
        timeout=timeout,
        polling=polling,
    )

to_have_selected_texts

to_have_selected_texts(texts: list[str], *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert [opt.text for opt in all_selected_options] == texts.

Source code in selenium_expect/assertions/select.py
def to_have_selected_texts(
    self,
    texts: list[str],
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert [opt.text for opt in all_selected_options] == texts."""
    if not texts:
        raise ValueError("texts list must not be empty")
    select = self._target

    def condition() -> tuple[bool, Any]:
        actual = [opt.text for opt in select.all_selected_options]
        return (actual == texts, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have selected texts {texts!r}",
        expected=texts,
        entity="select",
        timeout=timeout,
        polling=polling,
    )

to_have_selected_values

to_have_selected_values(values: list[str], *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert [opt.get_attribute('value') for opt in all_selected_options] == values.

Source code in selenium_expect/assertions/select.py
def to_have_selected_values(
    self,
    values: list[str],
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert [opt.get_attribute('value') for opt in all_selected_options] == values."""
    if not values:
        raise ValueError("values list must not be empty")
    select = self._target

    def condition() -> tuple[bool, Any]:
        actual = [opt.get_attribute("value") for opt in select.all_selected_options]
        return (actual == values, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have selected values {values!r}",
        expected=values,
        entity="select",
        timeout=timeout,
        polling=polling,
    )

to_have_value

to_have_value(value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert select.first_selected_option.get_attribute('value') == value.

Source code in selenium_expect/assertions/select.py
def to_have_value(
    self,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert select.first_selected_option.get_attribute('value') == value."""
    select = self._target

    def condition() -> tuple[bool, Any]:
        actual = select.first_selected_option.get_attribute("value")
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have value {value!r}",
        expected=value,
        entity="select",
        timeout=timeout,
        polling=polling,
    )

ExpectShadow

Assertions for ShadowRoot elements.

Methods: to_have_element, to_have_element_count, to_have_element_text, to_have_element_attribute, to_have_element_visible

selenium_expect.assertions.shadow.ExpectShadow

Bases: AssertionMixin

Assertions for ShadowRoot elements.

Source code in selenium_expect/assertions/shadow.py
class ExpectShadow(AssertionMixin):
    """Assertions for ShadowRoot elements."""

    def __init__(
        self,
        target: ShadowRoot,
        config: ExpectConfig | None = None,
        message: str | None = None,
        negate: bool = False,
    ) -> None:
        super().__init__(target=target, config=config, message=message, negate=negate)

    def to_have_element(
        self,
        by: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert shadow_root.find_element(by, value) doesn't raise."""
        shadow = self._target

        def condition() -> tuple[bool, Any]:
            try:
                el = shadow.find_element(by, value)
                return (True, el)
            except NoSuchElementException:
                return (False, "not found")

        self._run_assertion(
            condition=condition,
            condition_name=f"to have element ({by}={value!r})",
            expected="present",
            entity="shadow",
            timeout=timeout,
            polling=polling,
        )

    def to_have_element_count(
        self,
        by: str,
        value: str,
        count: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(shadow_root.find_elements(by, value)) == count."""
        shadow = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(shadow.find_elements(by, value))
            return (actual == count, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have element count {count} ({by}={value!r})",
            expected=count,
            entity="shadow",
            timeout=timeout,
            polling=polling,
        )

    def to_have_element_text(
        self,
        by: str,
        value: str,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert shadow_root.find_element(by, value).text == text."""
        shadow = self._target

        def condition() -> tuple[bool, Any]:
            try:
                el = shadow.find_element(by, value)
                actual = el.text
                return (actual == text, actual)
            except NoSuchElementException:
                return (False, "not found")

        self._run_assertion(
            condition=condition,
            condition_name=f"to have element text {text!r} ({by}={value!r})",
            expected=text,
            entity="shadow",
            timeout=timeout,
            polling=polling,
        )

    def to_have_element_attribute(
        self,
        by: str,
        value: str,
        attr: str,
        attr_value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert shadow_root.find_element(by, value).get_attribute(attr) == attr_value."""
        shadow = self._target

        def condition() -> tuple[bool, Any]:
            try:
                el = shadow.find_element(by, value)
                actual = el.get_attribute(attr)
                return (actual == attr_value, actual)
            except NoSuchElementException:
                return (False, "not found")

        self._run_assertion(
            condition=condition,
            condition_name=f"to have element attribute {attr!r}={attr_value!r} ({by}={value!r})",
            expected=attr_value,
            entity="shadow",
            timeout=timeout,
            polling=polling,
        )

    def to_have_element_visible(
        self,
        by: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert shadow_root.find_element(by, value).is_displayed() == True."""
        shadow = self._target

        def condition() -> tuple[bool, Any]:
            try:
                el = shadow.find_element(by, value)
                actual = el.is_displayed()
                return (actual is True, actual)
            except NoSuchElementException:
                return (False, "not found")

        self._run_assertion(
            condition=condition,
            condition_name=f"to have element visible ({by}={value!r})",
            expected=True,
            entity="shadow",
            timeout=timeout,
            polling=polling,
        )

    # --- Overrides ---

    def _entity_description(self) -> str:
        return "ShadowRoot"

    def _get_element_html(self) -> str | None:
        return None

to_have_element

to_have_element(by: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert shadow_root.find_element(by, value) doesn't raise.

Source code in selenium_expect/assertions/shadow.py
def to_have_element(
    self,
    by: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert shadow_root.find_element(by, value) doesn't raise."""
    shadow = self._target

    def condition() -> tuple[bool, Any]:
        try:
            el = shadow.find_element(by, value)
            return (True, el)
        except NoSuchElementException:
            return (False, "not found")

    self._run_assertion(
        condition=condition,
        condition_name=f"to have element ({by}={value!r})",
        expected="present",
        entity="shadow",
        timeout=timeout,
        polling=polling,
    )

to_have_element_attribute

to_have_element_attribute(by: str, value: str, attr: str, attr_value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert shadow_root.find_element(by, value).get_attribute(attr) == attr_value.

Source code in selenium_expect/assertions/shadow.py
def to_have_element_attribute(
    self,
    by: str,
    value: str,
    attr: str,
    attr_value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert shadow_root.find_element(by, value).get_attribute(attr) == attr_value."""
    shadow = self._target

    def condition() -> tuple[bool, Any]:
        try:
            el = shadow.find_element(by, value)
            actual = el.get_attribute(attr)
            return (actual == attr_value, actual)
        except NoSuchElementException:
            return (False, "not found")

    self._run_assertion(
        condition=condition,
        condition_name=f"to have element attribute {attr!r}={attr_value!r} ({by}={value!r})",
        expected=attr_value,
        entity="shadow",
        timeout=timeout,
        polling=polling,
    )

to_have_element_count

to_have_element_count(by: str, value: str, count: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(shadow_root.find_elements(by, value)) == count.

Source code in selenium_expect/assertions/shadow.py
def to_have_element_count(
    self,
    by: str,
    value: str,
    count: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(shadow_root.find_elements(by, value)) == count."""
    shadow = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(shadow.find_elements(by, value))
        return (actual == count, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have element count {count} ({by}={value!r})",
        expected=count,
        entity="shadow",
        timeout=timeout,
        polling=polling,
    )

to_have_element_text

to_have_element_text(by: str, value: str, text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert shadow_root.find_element(by, value).text == text.

Source code in selenium_expect/assertions/shadow.py
def to_have_element_text(
    self,
    by: str,
    value: str,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert shadow_root.find_element(by, value).text == text."""
    shadow = self._target

    def condition() -> tuple[bool, Any]:
        try:
            el = shadow.find_element(by, value)
            actual = el.text
            return (actual == text, actual)
        except NoSuchElementException:
            return (False, "not found")

    self._run_assertion(
        condition=condition,
        condition_name=f"to have element text {text!r} ({by}={value!r})",
        expected=text,
        entity="shadow",
        timeout=timeout,
        polling=polling,
    )

to_have_element_visible

to_have_element_visible(by: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert shadow_root.find_element(by, value).is_displayed() == True.

Source code in selenium_expect/assertions/shadow.py
def to_have_element_visible(
    self,
    by: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert shadow_root.find_element(by, value).is_displayed() == True."""
    shadow = self._target

    def condition() -> tuple[bool, Any]:
        try:
            el = shadow.find_element(by, value)
            actual = el.is_displayed()
            return (actual is True, actual)
        except NoSuchElementException:
            return (False, "not found")

    self._run_assertion(
        condition=condition,
        condition_name=f"to have element visible ({by}={value!r})",
        expected=True,
        entity="shadow",
        timeout=timeout,
        polling=polling,
    )

ExpectJS

Assertions for JavaScript and browser state.

Key method categories:

  • JS execution: to_have_js_result, to_have_js_result_contains, to_have_async_js_result, to_have_js_variable
  • localStorage: to_have_local_storage_item, to_have_local_storage_item_present, to_have_local_storage_item_absent, to_have_local_storage_length
  • sessionStorage: to_have_session_storage_item, to_have_session_storage_item_present, to_have_session_storage_item_absent, to_have_session_storage_length

selenium_expect.assertions.js.ExpectJS

Bases: AssertionMixin

Assertions for JavaScript / browser state via driver.execute_script.

Not dispatched via expect() (which maps WebDriver to ExpectDriver); instantiate directly with a driver.

Source code in selenium_expect/assertions/js.py
class ExpectJS(AssertionMixin):
    """Assertions for JavaScript / browser state via ``driver.execute_script``.

    Not dispatched via ``expect()`` (which maps ``WebDriver`` to
    ``ExpectDriver``); instantiate directly with a driver.
    """

    def __init__(
        self,
        target: WebDriver,
        config: ExpectConfig | None = None,
        message: str | None = None,
        negate: bool = False,
    ) -> None:
        super().__init__(target=target, config=config, message=message, negate=negate)

    # --- JS result ---

    def to_have_js_result(
        self,
        script: str,
        expected: Any,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.execute_script(script) == expected."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.execute_script(script)
            return (actual == expected, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have JS result {expected!r}",
            expected=expected,
            entity="js",
            timeout=timeout,
            polling=polling,
        )

    def to_have_js_result_contains(
        self,
        script: str,
        expected: Any,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert expected in driver.execute_script(script)."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.execute_script(script)
            if actual is None:
                return (False, actual)
            try:
                return (expected in actual, actual)
            except TypeError:
                return (False, f"not iterable: {actual!r}")

        self._run_assertion(
            condition=condition,
            condition_name=f"to have JS result containing {expected!r}",
            expected=expected,
            entity="js",
            timeout=timeout,
            polling=polling,
        )

    def to_have_js_result_matches(
        self,
        script: str,
        pattern: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert re.search(pattern, str(driver.execute_script(script)))."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.execute_script(script)
            return (re.search(pattern, str(actual)) is not None, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have JS result matching {pattern!r}",
            expected=pattern,
            entity="js",
            timeout=timeout,
            polling=polling,
        )

    def to_have_async_js_result(
        self,
        script: str,
        expected: Any,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.execute_async_script(script) == expected."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.execute_async_script(script)
            return (actual == expected, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have async JS result {expected!r}",
            expected=expected,
            entity="js",
            timeout=timeout,
            polling=polling,
        )

    # --- localStorage ---

    def to_have_local_storage_item(
        self,
        key: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert localStorage.getItem(key) == value via execute_script."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.execute_script("return localStorage.getItem(arguments[0]);", key)
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have localStorage item {key!r}={value!r}",
            expected=value,
            entity="js",
            timeout=timeout,
            polling=polling,
        )

    def to_have_local_storage_item_present(
        self,
        key: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert localStorage.getItem(key) is not None."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.execute_script("return localStorage.getItem(arguments[0]);", key)
            return (actual is not None, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have localStorage item {key!r} present",
            expected="not None",
            entity="js",
            timeout=timeout,
            polling=polling,
        )

    def to_have_local_storage_item_absent(
        self,
        key: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert localStorage.getItem(key) is None."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.execute_script("return localStorage.getItem(arguments[0]);", key)
            return (actual is None, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have localStorage item {key!r} absent",
            expected="None",
            entity="js",
            timeout=timeout,
            polling=polling,
        )

    def to_have_local_storage_length(
        self,
        length: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert localStorage.length == length."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.execute_script("return localStorage.length;")
            return (actual == length, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have localStorage length {length}",
            expected=length,
            entity="js",
            timeout=timeout,
            polling=polling,
        )

    # --- sessionStorage ---

    def to_have_session_storage_item(
        self,
        key: str,
        value: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert sessionStorage.getItem(key) == value."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.execute_script("return sessionStorage.getItem(arguments[0]);", key)
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have sessionStorage item {key!r}={value!r}",
            expected=value,
            entity="js",
            timeout=timeout,
            polling=polling,
        )

    def to_have_session_storage_item_present(
        self,
        key: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert sessionStorage.getItem(key) is not None."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.execute_script("return sessionStorage.getItem(arguments[0]);", key)
            return (actual is not None, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have sessionStorage item {key!r} present",
            expected="not None",
            entity="js",
            timeout=timeout,
            polling=polling,
        )

    def to_have_session_storage_item_absent(
        self,
        key: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert sessionStorage.getItem(key) is None."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.execute_script("return sessionStorage.getItem(arguments[0]);", key)
            return (actual is None, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have sessionStorage item {key!r} absent",
            expected="None",
            entity="js",
            timeout=timeout,
            polling=polling,
        )

    def to_have_session_storage_length(
        self,
        length: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert sessionStorage.length == length."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.execute_script("return sessionStorage.length;")
            return (actual == length, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have sessionStorage length {length}",
            expected=length,
            entity="js",
            timeout=timeout,
            polling=polling,
        )

    def to_have_js_variable(
        self,
        name: str,
        value: Any,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.execute_script('return window[name]') == value."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = driver.execute_script("return window[arguments[0]];", name)
            return (actual == value, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have JS variable {name!r}={value!r}",
            expected=value,
            entity="js",
            timeout=timeout,
            polling=polling,
        )

    # --- Overrides ---

    def _entity_description(self) -> str:
        return "JS"

    def _get_element_html(self) -> str | None:
        return None

to_have_async_js_result

to_have_async_js_result(script: str, expected: Any, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.execute_async_script(script) == expected.

Source code in selenium_expect/assertions/js.py
def to_have_async_js_result(
    self,
    script: str,
    expected: Any,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.execute_async_script(script) == expected."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.execute_async_script(script)
        return (actual == expected, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have async JS result {expected!r}",
        expected=expected,
        entity="js",
        timeout=timeout,
        polling=polling,
    )

to_have_js_result

to_have_js_result(script: str, expected: Any, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.execute_script(script) == expected.

Source code in selenium_expect/assertions/js.py
def to_have_js_result(
    self,
    script: str,
    expected: Any,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.execute_script(script) == expected."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.execute_script(script)
        return (actual == expected, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have JS result {expected!r}",
        expected=expected,
        entity="js",
        timeout=timeout,
        polling=polling,
    )

to_have_js_result_contains

to_have_js_result_contains(script: str, expected: Any, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert expected in driver.execute_script(script).

Source code in selenium_expect/assertions/js.py
def to_have_js_result_contains(
    self,
    script: str,
    expected: Any,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert expected in driver.execute_script(script)."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.execute_script(script)
        if actual is None:
            return (False, actual)
        try:
            return (expected in actual, actual)
        except TypeError:
            return (False, f"not iterable: {actual!r}")

    self._run_assertion(
        condition=condition,
        condition_name=f"to have JS result containing {expected!r}",
        expected=expected,
        entity="js",
        timeout=timeout,
        polling=polling,
    )

to_have_js_result_matches

to_have_js_result_matches(script: str, pattern: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert re.search(pattern, str(driver.execute_script(script))).

Source code in selenium_expect/assertions/js.py
def to_have_js_result_matches(
    self,
    script: str,
    pattern: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert re.search(pattern, str(driver.execute_script(script)))."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.execute_script(script)
        return (re.search(pattern, str(actual)) is not None, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have JS result matching {pattern!r}",
        expected=pattern,
        entity="js",
        timeout=timeout,
        polling=polling,
    )

to_have_js_variable

to_have_js_variable(name: str, value: Any, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.execute_script('return window[name]') == value.

Source code in selenium_expect/assertions/js.py
def to_have_js_variable(
    self,
    name: str,
    value: Any,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.execute_script('return window[name]') == value."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.execute_script("return window[arguments[0]];", name)
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have JS variable {name!r}={value!r}",
        expected=value,
        entity="js",
        timeout=timeout,
        polling=polling,
    )

to_have_local_storage_item

to_have_local_storage_item(key: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert localStorage.getItem(key) == value via execute_script.

Source code in selenium_expect/assertions/js.py
def to_have_local_storage_item(
    self,
    key: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert localStorage.getItem(key) == value via execute_script."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.execute_script("return localStorage.getItem(arguments[0]);", key)
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have localStorage item {key!r}={value!r}",
        expected=value,
        entity="js",
        timeout=timeout,
        polling=polling,
    )

to_have_local_storage_item_absent

to_have_local_storage_item_absent(key: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert localStorage.getItem(key) is None.

Source code in selenium_expect/assertions/js.py
def to_have_local_storage_item_absent(
    self,
    key: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert localStorage.getItem(key) is None."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.execute_script("return localStorage.getItem(arguments[0]);", key)
        return (actual is None, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have localStorage item {key!r} absent",
        expected="None",
        entity="js",
        timeout=timeout,
        polling=polling,
    )

to_have_local_storage_item_present

to_have_local_storage_item_present(key: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert localStorage.getItem(key) is not None.

Source code in selenium_expect/assertions/js.py
def to_have_local_storage_item_present(
    self,
    key: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert localStorage.getItem(key) is not None."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.execute_script("return localStorage.getItem(arguments[0]);", key)
        return (actual is not None, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have localStorage item {key!r} present",
        expected="not None",
        entity="js",
        timeout=timeout,
        polling=polling,
    )

to_have_local_storage_length

to_have_local_storage_length(length: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert localStorage.length == length.

Source code in selenium_expect/assertions/js.py
def to_have_local_storage_length(
    self,
    length: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert localStorage.length == length."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.execute_script("return localStorage.length;")
        return (actual == length, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have localStorage length {length}",
        expected=length,
        entity="js",
        timeout=timeout,
        polling=polling,
    )

to_have_session_storage_item

to_have_session_storage_item(key: str, value: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert sessionStorage.getItem(key) == value.

Source code in selenium_expect/assertions/js.py
def to_have_session_storage_item(
    self,
    key: str,
    value: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert sessionStorage.getItem(key) == value."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.execute_script("return sessionStorage.getItem(arguments[0]);", key)
        return (actual == value, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have sessionStorage item {key!r}={value!r}",
        expected=value,
        entity="js",
        timeout=timeout,
        polling=polling,
    )

to_have_session_storage_item_absent

to_have_session_storage_item_absent(key: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert sessionStorage.getItem(key) is None.

Source code in selenium_expect/assertions/js.py
def to_have_session_storage_item_absent(
    self,
    key: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert sessionStorage.getItem(key) is None."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.execute_script("return sessionStorage.getItem(arguments[0]);", key)
        return (actual is None, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have sessionStorage item {key!r} absent",
        expected="None",
        entity="js",
        timeout=timeout,
        polling=polling,
    )

to_have_session_storage_item_present

to_have_session_storage_item_present(key: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert sessionStorage.getItem(key) is not None.

Source code in selenium_expect/assertions/js.py
def to_have_session_storage_item_present(
    self,
    key: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert sessionStorage.getItem(key) is not None."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.execute_script("return sessionStorage.getItem(arguments[0]);", key)
        return (actual is not None, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have sessionStorage item {key!r} present",
        expected="not None",
        entity="js",
        timeout=timeout,
        polling=polling,
    )

to_have_session_storage_length

to_have_session_storage_length(length: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert sessionStorage.length == length.

Source code in selenium_expect/assertions/js.py
def to_have_session_storage_length(
    self,
    length: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert sessionStorage.length == length."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = driver.execute_script("return sessionStorage.length;")
        return (actual == length, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have sessionStorage length {length}",
        expected=length,
        entity="js",
        timeout=timeout,
        polling=polling,
    )

ExpectIframe

Assertions for iframes.

Methods: to_have_frame_available, to_have_frame_count, to_have_frame_count_greater_than, to_have_frame_text, to_be_in_frame, to_be_in_default_content

selenium_expect.assertions.iframe.ExpectIframe

Bases: AssertionMixin

Assertions for iframe/frame context.

Not dispatched via expect() (which maps WebDriver to ExpectDriver); instantiate directly with a driver.

Source code in selenium_expect/assertions/iframe.py
class ExpectIframe(AssertionMixin):
    """Assertions for iframe/frame context.

    Not dispatched via ``expect()`` (which maps ``WebDriver`` to
    ``ExpectDriver``); instantiate directly with a driver.
    """

    def __init__(
        self,
        target: WebDriver,
        config: ExpectConfig | None = None,
        message: str | None = None,
        negate: bool = False,
    ) -> None:
        super().__init__(target=target, config=config, message=message, negate=negate)

    def to_have_frame_available(
        self,
        frame_id: str | int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.switch_to.frame(frame_id) doesn't raise."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            try:
                driver.switch_to.frame(frame_id)
                driver.switch_to.default_content()
                return (True, "available")
            except NoSuchFrameException:
                return (False, "not available")

        self._run_assertion(
            condition=condition,
            condition_name=f"to have frame {frame_id!r} available",
            expected="available",
            entity="iframe",
            timeout=timeout,
            polling=polling,
        )

    def to_have_frame_count(
        self,
        count: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert len(driver.find_elements(By.TAG_NAME, 'iframe')) == count."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(driver.find_elements(By.TAG_NAME, "iframe"))
            return (actual == count, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have frame count {count}",
            expected=count,
            entity="iframe",
            timeout=timeout,
            polling=polling,
        )

    def to_have_frame_count_greater_than(
        self,
        n: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert iframe count > n."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            actual = len(driver.find_elements(By.TAG_NAME, "iframe"))
            return (actual > n, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have frame count > {n}",
            expected=f">{n}",
            entity="iframe",
            timeout=timeout,
            polling=polling,
        )

    def to_have_frame_text(
        self,
        frame_id: str | int,
        text: str,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Switch to frame, assert driver.page_source contains text, switch back."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            try:
                driver.switch_to.frame(frame_id)
                source = driver.page_source
                return (text in (source or ""), len(source) if source else 0)
            except NoSuchFrameException:
                return (False, "frame not available")
            finally:
                driver.switch_to.default_content()

        self._run_assertion(
            condition=condition,
            condition_name=f"to have frame {frame_id!r} text containing {text!r}",
            expected=text,
            entity="iframe",
            timeout=timeout,
            polling=polling,
        )

    def to_be_in_frame(
        self,
        frame_id: str | int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver is currently in the given frame (switch_to.frame succeeds)."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            try:
                driver.switch_to.frame(frame_id)
                return (True, "in frame")
            except NoSuchFrameException:
                return (False, "not in frame")

        self._run_assertion(
            condition=condition,
            condition_name=f"to be in frame {frame_id!r}",
            expected="in frame",
            entity="iframe",
            timeout=timeout,
            polling=polling,
        )

    def to_be_in_default_content(
        self,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver is in default content (not in any frame)."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            try:
                driver.switch_to.default_content()
                return (True, "in default content")
            except Exception as exc:
                return (False, str(exc))

        self._run_assertion(
            condition=condition,
            condition_name="to be in default content",
            expected="in default content",
            entity="iframe",
            timeout=timeout,
            polling=polling,
        )

    # --- Overrides ---

    def _entity_description(self) -> str:
        return "iframe"

    def _get_element_html(self) -> str | None:
        return None

to_be_in_default_content

to_be_in_default_content(*, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver is in default content (not in any frame).

Source code in selenium_expect/assertions/iframe.py
def to_be_in_default_content(
    self,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver is in default content (not in any frame)."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        try:
            driver.switch_to.default_content()
            return (True, "in default content")
        except Exception as exc:
            return (False, str(exc))

    self._run_assertion(
        condition=condition,
        condition_name="to be in default content",
        expected="in default content",
        entity="iframe",
        timeout=timeout,
        polling=polling,
    )

to_be_in_frame

to_be_in_frame(frame_id: str | int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver is currently in the given frame (switch_to.frame succeeds).

Source code in selenium_expect/assertions/iframe.py
def to_be_in_frame(
    self,
    frame_id: str | int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver is currently in the given frame (switch_to.frame succeeds)."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        try:
            driver.switch_to.frame(frame_id)
            return (True, "in frame")
        except NoSuchFrameException:
            return (False, "not in frame")

    self._run_assertion(
        condition=condition,
        condition_name=f"to be in frame {frame_id!r}",
        expected="in frame",
        entity="iframe",
        timeout=timeout,
        polling=polling,
    )

to_have_frame_available

to_have_frame_available(frame_id: str | int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.switch_to.frame(frame_id) doesn't raise.

Source code in selenium_expect/assertions/iframe.py
def to_have_frame_available(
    self,
    frame_id: str | int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.switch_to.frame(frame_id) doesn't raise."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        try:
            driver.switch_to.frame(frame_id)
            driver.switch_to.default_content()
            return (True, "available")
        except NoSuchFrameException:
            return (False, "not available")

    self._run_assertion(
        condition=condition,
        condition_name=f"to have frame {frame_id!r} available",
        expected="available",
        entity="iframe",
        timeout=timeout,
        polling=polling,
    )

to_have_frame_count

to_have_frame_count(count: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert len(driver.find_elements(By.TAG_NAME, 'iframe')) == count.

Source code in selenium_expect/assertions/iframe.py
def to_have_frame_count(
    self,
    count: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert len(driver.find_elements(By.TAG_NAME, 'iframe')) == count."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(driver.find_elements(By.TAG_NAME, "iframe"))
        return (actual == count, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have frame count {count}",
        expected=count,
        entity="iframe",
        timeout=timeout,
        polling=polling,
    )

to_have_frame_count_greater_than

to_have_frame_count_greater_than(n: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert iframe count > n.

Source code in selenium_expect/assertions/iframe.py
def to_have_frame_count_greater_than(
    self,
    n: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert iframe count > n."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        actual = len(driver.find_elements(By.TAG_NAME, "iframe"))
        return (actual > n, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have frame count > {n}",
        expected=f">{n}",
        entity="iframe",
        timeout=timeout,
        polling=polling,
    )

to_have_frame_text

to_have_frame_text(frame_id: str | int, text: str, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Switch to frame, assert driver.page_source contains text, switch back.

Source code in selenium_expect/assertions/iframe.py
def to_have_frame_text(
    self,
    frame_id: str | int,
    text: str,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Switch to frame, assert driver.page_source contains text, switch back."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        try:
            driver.switch_to.frame(frame_id)
            source = driver.page_source
            return (text in (source or ""), len(source) if source else 0)
        except NoSuchFrameException:
            return (False, "frame not available")
        finally:
            driver.switch_to.default_content()

    self._run_assertion(
        condition=condition,
        condition_name=f"to have frame {frame_id!r} text containing {text!r}",
        expected=text,
        entity="iframe",
        timeout=timeout,
        polling=polling,
    )

ExpectWindow

Assertions for browser window position, size, and rect.

Methods: to_have_position, to_have_size, to_have_rect

selenium_expect.assertions.window.ExpectWindow

Bases: AssertionMixin

Assertions for window position, size, and rect (driver-level).

Not dispatched via expect() (which maps WebDriver to ExpectDriver); instantiate directly with a driver.

Source code in selenium_expect/assertions/window.py
class ExpectWindow(AssertionMixin):
    """Assertions for window position, size, and rect (driver-level).

    Not dispatched via ``expect()`` (which maps ``WebDriver`` to
    ``ExpectDriver``); instantiate directly with a driver.
    """

    def __init__(
        self,
        target: WebDriver,
        config: ExpectConfig | None = None,
        message: str | None = None,
        negate: bool = False,
    ) -> None:
        super().__init__(target=target, config=config, message=message, negate=negate)

    def to_have_position(
        self,
        x: int,
        y: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.get_window_position() == {'x': x, 'y': y}."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            pos = driver.get_window_position()
            actual = {"x": pos["x"], "y": pos["y"]}
            return (actual == {"x": x, "y": y}, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have window position ({x}, {y})",
            expected={"x": x, "y": y},
            entity="window",
            timeout=timeout,
            polling=polling,
        )

    def to_have_size(
        self,
        width: int,
        height: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.get_window_size() == {'width': width, 'height': height}."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            sz = driver.get_window_size()
            actual = {"width": sz["width"], "height": sz["height"]}
            return (actual == {"width": width, "height": height}, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have window size ({width}x{height})",
            expected={"width": width, "height": height},
            entity="window",
            timeout=timeout,
            polling=polling,
        )

    def to_have_rect(
        self,
        x: int,
        y: int,
        width: int,
        height: int,
        *,
        timeout: float | None = None,
        polling: float | list[float] | None = None,
    ) -> None:
        """Assert driver.get_window_rect() matches all four values."""
        driver = self._target

        def condition() -> tuple[bool, Any]:
            rect = driver.get_window_rect()
            actual = {
                "x": rect["x"],
                "y": rect["y"],
                "width": rect["width"],
                "height": rect["height"],
            }
            expected = {"x": x, "y": y, "width": width, "height": height}
            return (actual == expected, actual)

        self._run_assertion(
            condition=condition,
            condition_name=f"to have window rect ({x}, {y}, {width}x{height})",
            expected={"x": x, "y": y, "width": width, "height": height},
            entity="window",
            timeout=timeout,
            polling=polling,
        )

    # --- Overrides ---

    def _entity_description(self) -> str:
        return "window"

    def _get_element_html(self) -> str | None:
        return None

to_have_position

to_have_position(x: int, y: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.get_window_position() == {'x': x, 'y': y}.

Source code in selenium_expect/assertions/window.py
def to_have_position(
    self,
    x: int,
    y: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.get_window_position() == {'x': x, 'y': y}."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        pos = driver.get_window_position()
        actual = {"x": pos["x"], "y": pos["y"]}
        return (actual == {"x": x, "y": y}, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have window position ({x}, {y})",
        expected={"x": x, "y": y},
        entity="window",
        timeout=timeout,
        polling=polling,
    )

to_have_rect

to_have_rect(x: int, y: int, width: int, height: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.get_window_rect() matches all four values.

Source code in selenium_expect/assertions/window.py
def to_have_rect(
    self,
    x: int,
    y: int,
    width: int,
    height: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.get_window_rect() matches all four values."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        rect = driver.get_window_rect()
        actual = {
            "x": rect["x"],
            "y": rect["y"],
            "width": rect["width"],
            "height": rect["height"],
        }
        expected = {"x": x, "y": y, "width": width, "height": height}
        return (actual == expected, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have window rect ({x}, {y}, {width}x{height})",
        expected={"x": x, "y": y, "width": width, "height": height},
        entity="window",
        timeout=timeout,
        polling=polling,
    )

to_have_size

to_have_size(width: int, height: int, *, timeout: float | None = None, polling: float | list[float] | None = None) -> None

Assert driver.get_window_size() == {'width': width, 'height': height}.

Source code in selenium_expect/assertions/window.py
def to_have_size(
    self,
    width: int,
    height: int,
    *,
    timeout: float | None = None,
    polling: float | list[float] | None = None,
) -> None:
    """Assert driver.get_window_size() == {'width': width, 'height': height}."""
    driver = self._target

    def condition() -> tuple[bool, Any]:
        sz = driver.get_window_size()
        actual = {"width": sz["width"], "height": sz["height"]}
        return (actual == {"width": width, "height": height}, actual)

    self._run_assertion(
        condition=condition,
        condition_name=f"to have window size ({width}x{height})",
        expected={"width": width, "height": height},
        entity="window",
        timeout=timeout,
        polling=polling,
    )

LocatorExpect

Locator-based expect that re-finds the element on each poll. All ExpectElement methods are available via delegation.

from selenium.webdriver.common.by import By
from selenium_expect import expect

# Re-finds element on each poll — avoids StaleElementReferenceException
expect(driver, by=By.ID, value="dynamic-element").to_be_visible(timeout=10)
expect(driver, locator=(By.CSS_SELECTOR, ".btn")).to_have_text("Submit")

selenium_expect._locator.LocatorExpect

Bases: AssertionMixin

Locator-based expect that re-finds the element on each poll.

Delegates all ExpectElement assertion methods via __getattr__. Each assertion method is executed with a fresh element obtained from driver.find_element(by, value) on every poll cycle.

Source code in selenium_expect/_locator.py
class LocatorExpect(AssertionMixin):
    """Locator-based expect that re-finds the element on each poll.

    Delegates all ``ExpectElement`` assertion methods via ``__getattr__``.
    Each assertion method is executed with a fresh element obtained from
    ``driver.find_element(by, value)`` on every poll cycle.
    """

    def __init__(
        self,
        driver: WebDriver,
        by: str,
        value: str,
        config: ExpectConfig | None = None,
        message: str | None = None,
        negate: bool = False,
    ) -> None:
        super().__init__(target=driver, config=config, message=message, negate=negate)
        self._driver = driver
        self._by = by
        self._value = value

    def _find_element(self) -> Any:
        """Find the element fresh. Returns None if not found."""
        try:
            return self._driver.find_element(self._by, self._value)
        except NoSuchElementException:
            return None

    @property
    def not_(self) -> LocatorExpect:
        """Return a negated copy."""
        return LocatorExpect(
            driver=self._driver,
            by=self._by,
            value=self._value,
            config=self._config,
            message=self._message,
            negate=not self._negate,
        )

    def _entity_description(self) -> str:
        return f"locator({self._by}={self._value!r})"

    def _get_element_html(self) -> str | None:
        el = self._find_element()
        if el is None:
            return None
        try:
            html: str | None = el.get_attribute("outerHTML")
            return html
        except StaleElementReferenceException:
            return None

    def __getattr__(self, name: str) -> Any:
        """Delegate to ExpectElement methods or custom matchers with re-find on each poll.

        For each assertion method call, we wrap the condition so that
        ``find_element`` is called fresh on every retry poll.
        """
        # Avoid recursion for private/dunder attributes
        if name.startswith("_"):
            raise AttributeError(f"{type(self).__name__!r} object has no attribute {name!r}")

        from selenium_expect._matcher import CustomMatcherRegistry
        from selenium_expect.assertions.element import ExpectElement

        # Check for custom matcher first
        matcher_fn = CustomMatcherRegistry.get(name)

        # Get the actual method from ExpectElement
        element_method = getattr(ExpectElement, name, None)

        if matcher_fn is None and (element_method is None or not callable(element_method)):
            raise AttributeError(f"{type(self).__name__!r} object has no attribute {name!r}")

        if matcher_fn is not None:

            def _invoke_matcher(*args: Any, **kwargs: Any) -> None:
                timeout = kwargs.pop("timeout", None)
                polling = kwargs.pop("polling", None)

                def condition() -> tuple[bool, Any]:
                    try:
                        el = self._driver.find_element(self._by, self._value)
                    except NoSuchElementException:
                        return (False, "element not found")
                    try:
                        return matcher_fn(el, *args, **kwargs)
                    except StaleElementReferenceException:
                        return (False, "stale element")

                self._run_assertion(
                    condition=condition,
                    condition_name=name.replace("_", " "),
                    expected=None,
                    entity=self._entity_description(),
                    timeout=timeout,
                    polling=polling,
                )

            return _invoke_matcher

        def _invoke(*args: Any, **kwargs: Any) -> None:
            timeout = kwargs.pop("timeout", None)
            polling = kwargs.pop("polling", None)

            def condition() -> tuple[bool, Any]:
                try:
                    el = self._driver.find_element(self._by, self._value)
                except NoSuchElementException:
                    return (False, "element not found")
                inner_config = self._config.replace(soft_mode=False, screenshot_on_failure=False)
                temp = ExpectElement(
                    target=el,
                    config=inner_config,
                    message=self._message,
                    negate=False,
                )
                method = getattr(temp, name)
                try:
                    method(*args, timeout=0.001, **kwargs)
                    return (True, "passed")
                except AssertionError:
                    return (False, "failed")
                except StaleElementReferenceException:
                    return (False, "stale element")

            self._run_assertion(
                condition=condition,
                condition_name=name.replace("_", " "),
                expected=None,
                entity=self._entity_description(),
                timeout=timeout,
                polling=polling,
            )

        return _invoke

not_ property

not_: LocatorExpect

Return a negated copy.

__getattr__

__getattr__(name: str) -> Any

Delegate to ExpectElement methods or custom matchers with re-find on each poll.

For each assertion method call, we wrap the condition so that find_element is called fresh on every retry poll.

Source code in selenium_expect/_locator.py
def __getattr__(self, name: str) -> Any:
    """Delegate to ExpectElement methods or custom matchers with re-find on each poll.

    For each assertion method call, we wrap the condition so that
    ``find_element`` is called fresh on every retry poll.
    """
    # Avoid recursion for private/dunder attributes
    if name.startswith("_"):
        raise AttributeError(f"{type(self).__name__!r} object has no attribute {name!r}")

    from selenium_expect._matcher import CustomMatcherRegistry
    from selenium_expect.assertions.element import ExpectElement

    # Check for custom matcher first
    matcher_fn = CustomMatcherRegistry.get(name)

    # Get the actual method from ExpectElement
    element_method = getattr(ExpectElement, name, None)

    if matcher_fn is None and (element_method is None or not callable(element_method)):
        raise AttributeError(f"{type(self).__name__!r} object has no attribute {name!r}")

    if matcher_fn is not None:

        def _invoke_matcher(*args: Any, **kwargs: Any) -> None:
            timeout = kwargs.pop("timeout", None)
            polling = kwargs.pop("polling", None)

            def condition() -> tuple[bool, Any]:
                try:
                    el = self._driver.find_element(self._by, self._value)
                except NoSuchElementException:
                    return (False, "element not found")
                try:
                    return matcher_fn(el, *args, **kwargs)
                except StaleElementReferenceException:
                    return (False, "stale element")

            self._run_assertion(
                condition=condition,
                condition_name=name.replace("_", " "),
                expected=None,
                entity=self._entity_description(),
                timeout=timeout,
                polling=polling,
            )

        return _invoke_matcher

    def _invoke(*args: Any, **kwargs: Any) -> None:
        timeout = kwargs.pop("timeout", None)
        polling = kwargs.pop("polling", None)

        def condition() -> tuple[bool, Any]:
            try:
                el = self._driver.find_element(self._by, self._value)
            except NoSuchElementException:
                return (False, "element not found")
            inner_config = self._config.replace(soft_mode=False, screenshot_on_failure=False)
            temp = ExpectElement(
                target=el,
                config=inner_config,
                message=self._message,
                negate=False,
            )
            method = getattr(temp, name)
            try:
                method(*args, timeout=0.001, **kwargs)
                return (True, "passed")
            except AssertionError:
                return (False, "failed")
            except StaleElementReferenceException:
                return (False, "stale element")

        self._run_assertion(
            condition=condition,
            condition_name=name.replace("_", " "),
            expected=None,
            entity=self._entity_description(),
            timeout=timeout,
            polling=polling,
        )

    return _invoke