diff --git a/pyproject.toml b/pyproject.toml index 1385049..9290a2a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -146,8 +146,8 @@ select = [ "T10", # flake8-debugger "T20", # flake8-print "TCH", # flake8-type-checking -# "TRY", # tryceratops -# "UP", # python upgrade + "TRY", # tryceratops + "UP", # python upgrade "W", # pycodestyle warning # "YTT", # flake8-2020 @@ -173,6 +173,7 @@ extend-safe-fixes = [ "D200", "D205", "D415", "PT003", "PT006", "PT018", "RET504", + "UP007", ] [tool.ruff.lint.per-file-ignores] diff --git a/screenpy_selenium/abilities/browse_the_web.py b/screenpy_selenium/abilities/browse_the_web.py index 5823ffb..7a8cd2a 100644 --- a/screenpy_selenium/abilities/browse_the_web.py +++ b/screenpy_selenium/abilities/browse_the_web.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import TYPE_CHECKING, Type, TypeVar +from typing import TYPE_CHECKING, TypeVar from selenium.webdriver import Chrome, Firefox, Remote, Safari @@ -35,22 +35,22 @@ class BrowseTheWeb: browser: WebDriver @classmethod - def using_chrome(cls: Type[SelfBrowseTheWeb]) -> SelfBrowseTheWeb: + def using_chrome(cls: type[SelfBrowseTheWeb]) -> SelfBrowseTheWeb: """Create and use a default Chrome Selenium webdriver instance.""" return cls.using(browser=Chrome()) @classmethod - def using_firefox(cls: Type[SelfBrowseTheWeb]) -> SelfBrowseTheWeb: + def using_firefox(cls: type[SelfBrowseTheWeb]) -> SelfBrowseTheWeb: """Create and use a default Firefox Selenium webdriver instance.""" return cls.using(browser=Firefox()) @classmethod - def using_safari(cls: Type[SelfBrowseTheWeb]) -> SelfBrowseTheWeb: + def using_safari(cls: type[SelfBrowseTheWeb]) -> SelfBrowseTheWeb: """Create and use a default Safari Selenium webdriver instance.""" return cls.using(browser=Safari()) @classmethod - def using_ios(cls: Type[SelfBrowseTheWeb]) -> SelfBrowseTheWeb: + def using_ios(cls: type[SelfBrowseTheWeb]) -> SelfBrowseTheWeb: """ Create and use a default Remote driver instance. @@ -83,7 +83,7 @@ def using_ios(cls: Type[SelfBrowseTheWeb]) -> SelfBrowseTheWeb: return cls.using(browser=Remote(hub_url, IOS_CAPABILITIES)) @classmethod - def using_android(cls: Type[SelfBrowseTheWeb]) -> SelfBrowseTheWeb: + def using_android(cls: type[SelfBrowseTheWeb]) -> SelfBrowseTheWeb: """ Create and use a default Remote driver instance. @@ -116,7 +116,7 @@ def using_android(cls: Type[SelfBrowseTheWeb]) -> SelfBrowseTheWeb: return cls.using(browser=Remote(hub_url, ANDROID_CAPABILITIES)) @classmethod - def using(cls: Type[SelfBrowseTheWeb], browser: WebDriver) -> SelfBrowseTheWeb: + def using(cls: type[SelfBrowseTheWeb], browser: WebDriver) -> SelfBrowseTheWeb: """Provide an already-set-up WebDriver to use to browse the web.""" return cls(browser=browser) diff --git a/screenpy_selenium/actions/clear.py b/screenpy_selenium/actions/clear.py index 08ff34e..ea0a621 100644 --- a/screenpy_selenium/actions/clear.py +++ b/screenpy_selenium/actions/clear.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Type, TypeVar +from typing import TYPE_CHECKING, TypeVar from screenpy.exceptions import DeliveryError from screenpy.pacing import beat @@ -28,7 +28,7 @@ class Clear: """ @classmethod - def the_text_from_the(cls: Type[SelfClear], target: Target) -> SelfClear: + def the_text_from_the(cls: type[SelfClear], target: Target) -> SelfClear: """ Specify the Target from which to clear the text. @@ -39,13 +39,13 @@ def the_text_from_the(cls: Type[SelfClear], target: Target) -> SelfClear: return cls(target=target) @classmethod - def the_text_from(cls: Type[SelfClear], target: Target) -> SelfClear: + def the_text_from(cls: type[SelfClear], target: Target) -> SelfClear: """Alias for :meth:`~screenpy_selenium.actions.Clear.the_text_from_the`.""" return cls.the_text_from_the(target=target) @classmethod def the_text_from_the_first_of_the( - cls: Type[SelfClear], target: Target + cls: type[SelfClear], target: Target ) -> SelfClear: """Alias for :meth:`~screenpy_selenium.actions.Clear.the_text_from_the`.""" return cls.the_text_from_the(target=target) diff --git a/screenpy_selenium/actions/click.py b/screenpy_selenium/actions/click.py index efa3391..c9093ec 100644 --- a/screenpy_selenium/actions/click.py +++ b/screenpy_selenium/actions/click.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Type, TypeVar +from typing import TYPE_CHECKING, TypeVar from screenpy.exceptions import DeliveryError, UnableToAct from screenpy.pacing import beat @@ -33,7 +33,7 @@ class Click: """ @classmethod - def on_the(cls: Type[SelfClick], target: Target) -> SelfClick: + def on_the(cls: type[SelfClick], target: Target) -> SelfClick: """ Target the element to click on. @@ -44,12 +44,12 @@ def on_the(cls: Type[SelfClick], target: Target) -> SelfClick: return cls(target=target) @classmethod - def on(cls: Type[SelfClick], target: Target) -> SelfClick: + def on(cls: type[SelfClick], target: Target) -> SelfClick: """Alias for :meth:`~screenpy_selenium.actions.Click.on_the`.""" return cls.on_the(target=target) @classmethod - def on_the_first_of_the(cls: Type[SelfClick], target: Target) -> SelfClick: + def on_the_first_of_the(cls: type[SelfClick], target: Target) -> SelfClick: """Alias for :meth:`~screenpy_selenium.actions.Click.on_the`.""" return cls.on_the(target=target) @@ -90,6 +90,6 @@ def add_to_chain( the_chain.click(on_element=the_element) - def __init__(self: SelfClick, target: Optional[Target] = None) -> None: + def __init__(self: SelfClick, target: Target | None = None) -> None: self.target = target self.description = f" on the {target}" if target is not None else "" diff --git a/screenpy_selenium/actions/double_click.py b/screenpy_selenium/actions/double_click.py index 4601722..c22728a 100644 --- a/screenpy_selenium/actions/double_click.py +++ b/screenpy_selenium/actions/double_click.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Type, TypeVar +from typing import TYPE_CHECKING, TypeVar from screenpy.pacing import beat from selenium.webdriver.common.action_chains import ActionChains @@ -30,10 +30,10 @@ class DoubleClick: the_actor.attempts_to(Chain(DoubleClick())) """ - target: Optional[Target] + target: Target | None @classmethod - def on_the(cls: Type[SelfDoubleClick], target: Target) -> SelfDoubleClick: + def on_the(cls: type[SelfDoubleClick], target: Target) -> SelfDoubleClick: """ Target the element to double-click on. @@ -44,13 +44,13 @@ def on_the(cls: Type[SelfDoubleClick], target: Target) -> SelfDoubleClick: return cls(target=target) @classmethod - def on(cls: Type[SelfDoubleClick], target: Target) -> SelfDoubleClick: + def on(cls: type[SelfDoubleClick], target: Target) -> SelfDoubleClick: """Alias for :meth:`~screenpy_selenium.actions.DoubleClick.on_the`.""" return cls.on_the(target=target) @classmethod def on_the_first_of_the( - cls: Type[SelfDoubleClick], target: Target + cls: type[SelfDoubleClick], target: Target ) -> SelfDoubleClick: """Alias for :meth:`~screenpy_selenium.actions.DoubleClick.on_the`.""" return cls.on_the(target=target) @@ -85,6 +85,6 @@ def add_to_chain( """Add the DoubleClick Action to a Chain of Actions.""" self._add_action_to_chain(the_actor, the_chain) - def __init__(self: SelfDoubleClick, target: Optional[Target] = None) -> None: + def __init__(self: SelfDoubleClick, target: Target | None = None) -> None: self.target = target self.description = f" on the {target}" if target is not None else "" diff --git a/screenpy_selenium/actions/enter.py b/screenpy_selenium/actions/enter.py index 37dfcf1..fcdba36 100644 --- a/screenpy_selenium/actions/enter.py +++ b/screenpy_selenium/actions/enter.py @@ -3,7 +3,7 @@ from __future__ import annotations from functools import partial -from typing import TYPE_CHECKING, List, Optional, Type, TypeVar +from typing import TYPE_CHECKING, TypeVar from screenpy.exceptions import DeliveryError, UnableToAct from screenpy.pacing import aside, beat @@ -33,13 +33,13 @@ class Enter: ) """ - target: Optional[Target] - following_keys: List[str] + target: Target | None + following_keys: list[str] text: str text_to_log: str @classmethod - def the_text(cls: Type[SelfEnter], text: str) -> SelfEnter: + def the_text(cls: type[SelfEnter], text: str) -> SelfEnter: """Provide the text to enter into the field. Aliases: @@ -48,12 +48,12 @@ def the_text(cls: Type[SelfEnter], text: str) -> SelfEnter: return cls(text=text) @classmethod - def the_keys(cls: Type[SelfEnter], text: str) -> SelfEnter: + def the_keys(cls: type[SelfEnter], text: str) -> SelfEnter: """Alias for :meth:`~screenpy_selenium.actions.Enter.the_text`.""" return cls.the_text(text=text) @classmethod - def the_secret(cls: Type[SelfEnter], text: str) -> SelfEnter: + def the_secret(cls: type[SelfEnter], text: str) -> SelfEnter: """ Provide the text to enter into the field, but mask it in logging. @@ -65,7 +65,7 @@ def the_secret(cls: Type[SelfEnter], text: str) -> SelfEnter: return cls(text=text, mask=True) @classmethod - def the_password(cls: Type[SelfEnter], text: str) -> SelfEnter: + def the_password(cls: type[SelfEnter], text: str) -> SelfEnter: """Alias for :meth:`~screenpy_selenium.actions.Enter.the_secret`.""" return cls.the_secret(text=text) diff --git a/screenpy_selenium/actions/enter_2fa_token.py b/screenpy_selenium/actions/enter_2fa_token.py index 1bf3e66..c490e01 100644 --- a/screenpy_selenium/actions/enter_2fa_token.py +++ b/screenpy_selenium/actions/enter_2fa_token.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Type, TypeVar +from typing import TYPE_CHECKING, TypeVar from screenpy.pacing import beat from screenpy_pyotp.abilities import AuthenticateWith2FA @@ -31,7 +31,7 @@ class Enter2FAToken: """ @classmethod - def into_the(cls: Type[SelfEnter2FAToken], target: Target) -> SelfEnter2FAToken: + def into_the(cls: type[SelfEnter2FAToken], target: Target) -> SelfEnter2FAToken: """ Target the element into which to enter the 2FA token. @@ -41,7 +41,7 @@ def into_the(cls: Type[SelfEnter2FAToken], target: Target) -> SelfEnter2FAToken: return cls(target) @classmethod - def into(cls: Type[SelfEnter2FAToken], target: Target) -> SelfEnter2FAToken: + def into(cls: type[SelfEnter2FAToken], target: Target) -> SelfEnter2FAToken: """Alias for :meth:`~screenpy_selenium.actions.Enter2FAToken.into_the`.""" return cls.into_the(target=target) diff --git a/screenpy_selenium/actions/hold_down.py b/screenpy_selenium/actions/hold_down.py index 1d03df5..9acbac5 100644 --- a/screenpy_selenium/actions/hold_down.py +++ b/screenpy_selenium/actions/hold_down.py @@ -3,7 +3,7 @@ from __future__ import annotations import platform -from typing import TYPE_CHECKING, Optional, Type, TypeVar +from typing import TYPE_CHECKING, TypeVar from screenpy.exceptions import UnableToAct from screenpy.pacing import beat @@ -41,13 +41,13 @@ class HoldDown: ) """ - target: Optional[Target] - key: Optional[str] + target: Target | None + key: str | None lmb: bool description: str @classmethod - def command_or_control_key(cls: Type[SelfHoldDown]) -> SelfHoldDown: + def command_or_control_key(cls: type[SelfHoldDown]) -> SelfHoldDown: """ A convenience method for supporting multiple operating systems. @@ -59,7 +59,7 @@ def command_or_control_key(cls: Type[SelfHoldDown]) -> SelfHoldDown: return cls(Keys.CONTROL) @classmethod - def left_mouse_button(cls: Type[SelfHoldDown]) -> SelfHoldDown: + def left_mouse_button(cls: type[SelfHoldDown]) -> SelfHoldDown: """Hold down the left mouse button.""" return cls(lmb=True) @@ -88,9 +88,7 @@ def add_to_chain( msg = "HoldDown must be told what to hold down." raise UnableToAct(msg) - def __init__( - self: SelfHoldDown, key: Optional[str] = None, lmb: bool = False - ) -> None: + def __init__(self: SelfHoldDown, key: str | None = None, lmb: bool = False) -> None: self.key = key self.lmb = lmb self.target = None diff --git a/screenpy_selenium/actions/move_mouse.py b/screenpy_selenium/actions/move_mouse.py index ed386ed..78152ed 100644 --- a/screenpy_selenium/actions/move_mouse.py +++ b/screenpy_selenium/actions/move_mouse.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Tuple, Type, TypeVar +from typing import TYPE_CHECKING, TypeVar from screenpy.exceptions import UnableToAct from screenpy.pacing import beat @@ -43,12 +43,12 @@ class MoveMouse: ) """ - offset: Optional[Tuple[int, int]] - target: Optional[Target] + offset: tuple[int, int] | None + target: Target | None description: str @classmethod - def to_the(cls: Type[SelfMoveMouse], target: Target) -> SelfMoveMouse: + def to_the(cls: type[SelfMoveMouse], target: Target) -> SelfMoveMouse: """ Target an element to move the mouse to. @@ -61,30 +61,30 @@ def to_the(cls: Type[SelfMoveMouse], target: Target) -> SelfMoveMouse: return cls(target=target, description=f"to the {target}") @classmethod - def on_the(cls: Type[SelfMoveMouse], target: Target) -> SelfMoveMouse: + def on_the(cls: type[SelfMoveMouse], target: Target) -> SelfMoveMouse: """Alias for :meth:`~screenpy_selenium.actions.MoveMouse.to_the`.""" return cls.to_the(target=target) @classmethod - def over_the(cls: Type[SelfMoveMouse], target: Target) -> SelfMoveMouse: + def over_the(cls: type[SelfMoveMouse], target: Target) -> SelfMoveMouse: """Alias for :meth:`~screenpy_selenium.actions.MoveMouse.to_the`.""" return cls.to_the(target=target) @classmethod def over_the_first_of_the( - cls: Type[SelfMoveMouse], target: Target + cls: type[SelfMoveMouse], target: Target ) -> SelfMoveMouse: """Alias for :meth:`~screenpy_selenium.actions.MoveMouse.to_the`.""" return cls.to_the(target=target) @classmethod - def to_the_first_of_the(cls: Type[SelfMoveMouse], target: Target) -> SelfMoveMouse: + def to_the_first_of_the(cls: type[SelfMoveMouse], target: Target) -> SelfMoveMouse: """Alias for :meth:`~screenpy_selenium.actions.MoveMouse.to_the`.""" return cls.to_the(target=target) @classmethod def by_offset( - cls: Type[SelfMoveMouse], x_offset: int, y_offset: int + cls: type[SelfMoveMouse], x_offset: int, y_offset: int ) -> SelfMoveMouse: """Specify the offset by which to move the mouse.""" return cls( @@ -138,8 +138,8 @@ def add_to_chain( def __init__( self: SelfMoveMouse, - offset: Optional[Tuple[int, int]] = None, - target: Optional[Target] = None, + offset: tuple[int, int] | None = None, + target: Target | None = None, description: str = "", ) -> None: self.offset = offset diff --git a/screenpy_selenium/actions/open.py b/screenpy_selenium/actions/open.py index 8c75c40..5980d0b 100644 --- a/screenpy_selenium/actions/open.py +++ b/screenpy_selenium/actions/open.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import TYPE_CHECKING, Type, TypeVar, Union +from typing import TYPE_CHECKING, TypeVar from screenpy.pacing import beat @@ -42,7 +42,7 @@ class Open: """ @classmethod - def their_browser_on(cls: Type[SelfOpen], location: Union[str, object]) -> SelfOpen: + def their_browser_on(cls: type[SelfOpen], location: str | object) -> SelfOpen: """ Provide a URL to visit. @@ -52,7 +52,7 @@ def their_browser_on(cls: Type[SelfOpen], location: Union[str, object]) -> SelfO return cls(location=location) @classmethod - def browser_on(cls: Type[SelfOpen], location: Union[str, object]) -> SelfOpen: + def browser_on(cls: type[SelfOpen], location: str | object) -> SelfOpen: """Alias for :meth:`~screenpy_selenium.actions.Open.their_browser_on`.""" return cls.their_browser_on(location=location) @@ -66,7 +66,7 @@ def perform_as(self: SelfOpen, the_actor: Actor) -> None: browser = the_actor.ability_to(BrowseTheWeb).browser browser.get(self.url) - def __init__(self: SelfOpen, location: Union[str, object]) -> None: + def __init__(self: SelfOpen, location: str | object) -> None: url = getattr(location, "url", location) url = f'{os.getenv("BASE_URL", "")}{url}' self.url = url diff --git a/screenpy_selenium/actions/release.py b/screenpy_selenium/actions/release.py index 1f165cf..d7afc04 100644 --- a/screenpy_selenium/actions/release.py +++ b/screenpy_selenium/actions/release.py @@ -3,7 +3,7 @@ from __future__ import annotations import platform -from typing import TYPE_CHECKING, Optional, Type, TypeVar +from typing import TYPE_CHECKING, TypeVar from screenpy.exceptions import UnableToAct from screenpy.pacing import beat @@ -37,13 +37,13 @@ class Release: the_actor.attempts_to(Release.command_or_control_key()) """ - key: Optional[str] + key: str | None lmb: bool description: str the_kraken: str @classmethod - def command_or_control_key(cls: Type[SelfRelease]) -> SelfRelease: + def command_or_control_key(cls: type[SelfRelease]) -> SelfRelease: """ A convenience method for supporting multiple operating systems. @@ -55,7 +55,7 @@ def command_or_control_key(cls: Type[SelfRelease]) -> SelfRelease: return cls(key=Keys.CONTROL) @classmethod - def left_mouse_button(cls: Type[SelfRelease]) -> SelfRelease: + def left_mouse_button(cls: type[SelfRelease]) -> SelfRelease: """Release the left mouse button.""" return cls(lmb=True) @@ -75,9 +75,7 @@ def add_to_chain(self: SelfRelease, _: Actor, the_chain: ActionChains) -> None: msg = "Release must be told what to release." raise UnableToAct(msg) - def __init__( - self: SelfRelease, key: Optional[str] = None, lmb: bool = False - ) -> None: + def __init__(self: SelfRelease, key: str | None = None, lmb: bool = False) -> None: self.key = key self.lmb = lmb self.description = "LEFT MOUSE BUTTON" if lmb else KEY_NAMES[key] diff --git a/screenpy_selenium/actions/respond_to_the_prompt.py b/screenpy_selenium/actions/respond_to_the_prompt.py index bb0752f..9d201de 100644 --- a/screenpy_selenium/actions/respond_to_the_prompt.py +++ b/screenpy_selenium/actions/respond_to_the_prompt.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Type, TypeVar +from typing import TYPE_CHECKING, TypeVar from screenpy.pacing import aside, beat @@ -28,7 +28,7 @@ class RespondToThePrompt: """ @classmethod - def with_(cls: Type[SelfRespondToThePrompt], text: str) -> SelfRespondToThePrompt: + def with_(cls: type[SelfRespondToThePrompt], text: str) -> SelfRespondToThePrompt: """Provide the text to enter into the prompt.""" return cls(text) diff --git a/screenpy_selenium/actions/right_click.py b/screenpy_selenium/actions/right_click.py index 3e463d2..d915370 100644 --- a/screenpy_selenium/actions/right_click.py +++ b/screenpy_selenium/actions/right_click.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Type, TypeVar +from typing import TYPE_CHECKING, TypeVar from screenpy.pacing import beat from selenium.webdriver.common.action_chains import ActionChains @@ -35,10 +35,10 @@ class RightClick: context menu made of web elements to be able to interact with it. """ - target: Optional[Target] + target: Target | None @classmethod - def on_the(cls: Type[SelfRightClick], target: Target) -> SelfRightClick: + def on_the(cls: type[SelfRightClick], target: Target) -> SelfRightClick: """Target an element to right-click on. Aliases: @@ -48,13 +48,13 @@ def on_the(cls: Type[SelfRightClick], target: Target) -> SelfRightClick: return cls(target=target) @classmethod - def on(cls: Type[SelfRightClick], target: Target) -> SelfRightClick: + def on(cls: type[SelfRightClick], target: Target) -> SelfRightClick: """Alias for :meth:`~screenpy_selenium.actions.RightClick.on_the`.""" return cls.on_the(target=target) @classmethod def on_the_first_of_the( - cls: Type[SelfRightClick], target: Target + cls: type[SelfRightClick], target: Target ) -> SelfRightClick: """Alias for :meth:`~screenpy_selenium.actions.RightClick.on_the`.""" return cls.on_the(target=target) @@ -89,6 +89,6 @@ def add_to_chain( """Add the RightClick Action to a Chain of Actions.""" self._add_action_to_chain(the_actor, the_chain) - def __init__(self: SelfRightClick, target: Optional[Target] = None) -> None: + def __init__(self: SelfRightClick, target: Target | None = None) -> None: self.target = target self.description = f" on the {target}" if target is not None else "" diff --git a/screenpy_selenium/actions/save_console_log.py b/screenpy_selenium/actions/save_console_log.py index 42c637a..fad9612 100644 --- a/screenpy_selenium/actions/save_console_log.py +++ b/screenpy_selenium/actions/save_console_log.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import TYPE_CHECKING, Any, Optional, Type, TypeVar +from typing import TYPE_CHECKING, Any, TypeVar from screenpy.actions import AttachTheFile from screenpy.pacing import beat @@ -49,7 +49,7 @@ class SaveConsoleLog: ) """ - attach_kwargs: Optional[dict] + attach_kwargs: dict | None path: str filename: str @@ -58,7 +58,7 @@ def describe(self: SelfSaveConsoleLog) -> str: return f"Save browser console log as {self.filename}" @classmethod - def as_(cls: Type[SelfSaveConsoleLog], path: str) -> SelfSaveConsoleLog: + def as_(cls: type[SelfSaveConsoleLog], path: str) -> SelfSaveConsoleLog: """Supply the name and/or filepath for the saved text file. If only a name is supplied, the text file will appear in the current diff --git a/screenpy_selenium/actions/save_screenshot.py b/screenpy_selenium/actions/save_screenshot.py index 19be366..d582a4e 100644 --- a/screenpy_selenium/actions/save_screenshot.py +++ b/screenpy_selenium/actions/save_screenshot.py @@ -3,7 +3,7 @@ from __future__ import annotations import os -from typing import TYPE_CHECKING, Any, Optional, Type, TypeVar +from typing import TYPE_CHECKING, Any, TypeVar from screenpy.actions import AttachTheFile from screenpy.pacing import beat @@ -45,7 +45,7 @@ class SaveScreenshot: ) """ - attach_kwargs: Optional[dict] + attach_kwargs: dict | None path: str filename: str @@ -54,7 +54,7 @@ def describe(self: SelfSaveScreenshot) -> str: return f"Save screenshot as {self.filename}" @classmethod - def as_(cls: Type[SelfSaveScreenshot], path: str) -> SelfSaveScreenshot: + def as_(cls: type[SelfSaveScreenshot], path: str) -> SelfSaveScreenshot: """Supply the name and/or filepath for the screenshot. If only a name is supplied, the screenshot will appear in the current diff --git a/screenpy_selenium/actions/select.py b/screenpy_selenium/actions/select.py index d25ac94..2c70a0b 100644 --- a/screenpy_selenium/actions/select.py +++ b/screenpy_selenium/actions/select.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, TypeVar, Union +from typing import TYPE_CHECKING, TypeVar from screenpy.exceptions import DeliveryError, UnableToAct from screenpy.pacing import beat @@ -44,17 +44,17 @@ class Select: """ @staticmethod - def the_option_named(text: str) -> "SelectByText": + def the_option_named(text: str) -> SelectByText: """Select the option by its text.""" return SelectByText(text) @staticmethod - def the_option_at_index(index: Union[int, str]) -> "SelectByIndex": + def the_option_at_index(index: int | str) -> SelectByIndex: """Select the option by its index. This index is 0-based.""" return SelectByIndex(index) @staticmethod - def the_option_with_value(value: Union[int, str]) -> "SelectByValue": + def the_option_with_value(value: int | str) -> SelectByValue: """Select the option by its value.""" return SelectByValue(value) @@ -69,7 +69,7 @@ class SelectByText: :class:`~screenpy_selenium.abilities.BrowseTheWeb` """ - target: Optional[Target] + target: Target | None text: str def from_the(self: SelfSelectByText, target: Target) -> SelfSelectByText: @@ -105,7 +105,7 @@ def perform_as(self: SelfSelectByText, the_actor: Actor) -> None: raise DeliveryError(msg) from e def __init__( - self: SelfSelectByText, text: str, target: Optional[Target] = None + self: SelfSelectByText, text: str, target: Target | None = None ) -> None: self.target = target self.text = text @@ -121,7 +121,7 @@ class SelectByIndex: :class:`~screenpy_selenium.abilities.BrowseTheWeb` """ - target: Optional[Target] + target: Target | None index: int def from_the(self: SelfSelectByIndex, target: Target) -> SelfSelectByIndex: @@ -157,7 +157,7 @@ def perform_as(self: SelfSelectByIndex, the_actor: Actor) -> None: raise DeliveryError(msg) from e def __init__( - self: SelfSelectByIndex, index: Union[int, str], target: Optional[Target] = None + self: SelfSelectByIndex, index: int | str, target: Target | None = None ) -> None: self.target = target self.index = int(index) @@ -173,7 +173,7 @@ class SelectByValue: :class:`~screenpy_selenium.abilities.BrowseTheWeb` """ - target: Optional[Target] + target: Target | None value: str def from_the(self: SelfSelectByValue, target: Target) -> SelfSelectByValue: @@ -209,7 +209,7 @@ def perform_as(self: SelfSelectByValue, the_actor: Actor) -> None: raise DeliveryError(msg) from e def __init__( - self: SelfSelectByValue, value: Union[int, str], target: Optional[Target] = None + self: SelfSelectByValue, value: int | str, target: Target | None = None ) -> None: self.target = target self.value = str(value) diff --git a/screenpy_selenium/actions/switch_to.py b/screenpy_selenium/actions/switch_to.py index 69203fe..eecde46 100644 --- a/screenpy_selenium/actions/switch_to.py +++ b/screenpy_selenium/actions/switch_to.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional, Type, TypeVar +from typing import TYPE_CHECKING, TypeVar from screenpy.pacing import beat @@ -32,12 +32,12 @@ class SwitchTo: """ @classmethod - def the(cls: Type[SelfSwitchTo], target: Target) -> SelfSwitchTo: + def the(cls: type[SelfSwitchTo], target: Target) -> SelfSwitchTo: """Target an element, probably an iframe, to switch to.""" return cls(target=target, frame_to_log=str(target)) @classmethod - def default(cls: Type[SelfSwitchTo]) -> SelfSwitchTo: + def default(cls: type[SelfSwitchTo]) -> SelfSwitchTo: """Switch back to the default frame, the browser window.""" return cls(target=None, frame_to_log="default frame") @@ -54,8 +54,6 @@ def perform_as(self: SelfSwitchTo, the_actor: Actor) -> None: else: browser.switch_to.frame(self.target.found_by(the_actor)) - def __init__( - self: SelfSwitchTo, target: Optional[Target], frame_to_log: str - ) -> None: + def __init__(self: SelfSwitchTo, target: Target | None, frame_to_log: str) -> None: self.target = target self.frame_to_log = frame_to_log diff --git a/screenpy_selenium/actions/wait.py b/screenpy_selenium/actions/wait.py index b4d6dbb..94ca3a6 100644 --- a/screenpy_selenium/actions/wait.py +++ b/screenpy_selenium/actions/wait.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Iterable, Optional, Type, TypeVar +from typing import TYPE_CHECKING, Any, Callable, Iterable, TypeVar from screenpy import Actor, settings from screenpy.exceptions import DeliveryError @@ -52,10 +52,10 @@ class Wait: args: Iterable[Any] timeout: float - log_detail: Optional[str] + log_detail: str | None @classmethod - def for_the(cls: Type[SelfWait], target: Target) -> SelfWait: + def for_the(cls: type[SelfWait], target: Target) -> SelfWait: """Set the Target to wait for. Aliases: @@ -64,7 +64,7 @@ def for_the(cls: Type[SelfWait], target: Target) -> SelfWait: return cls(seconds=settings.TIMEOUT, args=[target]) @classmethod - def for_(cls: Type[SelfWait], target: Target) -> SelfWait: + def for_(cls: type[SelfWait], target: Target) -> SelfWait: """Alias for :meth:`~screenpy_selenium.actions.Wait.for_the`.""" return cls.for_the(target=target) @@ -76,7 +76,7 @@ def seconds_for_the(self: SelfWait, target: Target) -> SelfWait: second_for = second_for_the = seconds_for = seconds_for_the def using( - self: SelfWait, strategy: Callable[..., Any], log_detail: Optional[str] = None + self: SelfWait, strategy: Callable[..., Any], log_detail: str | None = None ) -> SelfWait: """Use the given strategy to wait for the Target. @@ -149,8 +149,8 @@ def perform_as(self: SelfWait, the_actor: Actor) -> None: def __init__( self: SelfWait, - seconds: Optional[float] = None, - args: Optional[Iterable[Any]] = None, + seconds: float | None = None, + args: Iterable[Any] | None = None, ) -> None: self.args = args if args is not None else [] self.timeout = seconds if seconds is not None else settings.TIMEOUT diff --git a/screenpy_selenium/questions/attribute.py b/screenpy_selenium/questions/attribute.py index dcaa0dc..1fb414b 100644 --- a/screenpy_selenium/questions/attribute.py +++ b/screenpy_selenium/questions/attribute.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Optional, Union +from typing import TYPE_CHECKING from screenpy.exceptions import UnableToAnswer from screenpy.pacing import beat @@ -31,16 +31,16 @@ class Attribute: ) """ - target: Optional[Target] + target: Target | None - def of_the(self, target: Target) -> "Attribute": + def of_the(self, target: Target) -> Attribute: """Target the element to get the attribute from.""" self.target = target return self of = of_the_first_of_the = of_the - def of_all(self, target: Target) -> "Attribute": + def of_all(self, target: Target) -> Attribute: """Target the elements, plural, to get the attribute from.""" self.target = target self.multi = True @@ -51,7 +51,7 @@ def describe(self) -> str: return f'The "{self.attribute}" attribute of the {self.target}.' @beat('{} examines the "{attribute}" attribute of the {target}...') - def answered_by(self, the_actor: Actor) -> Union[str, List[Union[str, None]], None]: + def answered_by(self, the_actor: Actor) -> str | list[str | None] | None: """Direct the actor to investigate the attribute on the element.""" if self.target is None: msg = ( diff --git a/screenpy_selenium/questions/element.py b/screenpy_selenium/questions/element.py index 08bfe8d..4b8ee10 100644 --- a/screenpy_selenium/questions/element.py +++ b/screenpy_selenium/questions/element.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING from screenpy.pacing import beat @@ -26,14 +26,14 @@ class Element: the_actor.should(See.the(Element(WELCOME_BANNER), IsVisible())) """ - caught_exception: Optional[TargetingError] + caught_exception: TargetingError | None def describe(self) -> str: """Describe the Question.""" return f"The {self.target}." @beat("{} inspects the {target}.") - def answered_by(self, the_actor: Actor) -> Optional[WebElement]: + def answered_by(self, the_actor: Actor) -> WebElement | None: """Direct the Actor to find the element.""" try: return self.target.found_by(the_actor) diff --git a/screenpy_selenium/questions/list.py b/screenpy_selenium/questions/list.py index edd46ca..d6af340 100644 --- a/screenpy_selenium/questions/list.py +++ b/screenpy_selenium/questions/list.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List as ListType, Type, TypeVar +from typing import TYPE_CHECKING, TypeVar from screenpy.pacing import beat @@ -27,7 +27,7 @@ class List: """ @classmethod - def of_the(cls: Type[SelfList], target: Target) -> SelfList: + def of_the(cls: type[SelfList], target: Target) -> SelfList: """Target the element(s) to list. Aliases: @@ -38,17 +38,17 @@ def of_the(cls: Type[SelfList], target: Target) -> SelfList: return cls(target=target) @classmethod - def of_all_the(cls: Type[SelfList], target: Target) -> SelfList: + def of_all_the(cls: type[SelfList], target: Target) -> SelfList: """Alias for :meth:`~screenpy_selenium.actions.List.of_the`.""" return cls.of_the(target=target) @classmethod - def of_all(cls: Type[SelfList], target: Target) -> SelfList: + def of_all(cls: type[SelfList], target: Target) -> SelfList: """Alias for :meth:`~screenpy_selenium.actions.List.of_the`.""" return cls.of_the(target=target) @classmethod - def of(cls: Type[SelfList], target: Target) -> SelfList: + def of(cls: type[SelfList], target: Target) -> SelfList: """Alias for :meth:`~screenpy_selenium.actions.List.of_the`.""" return cls.of_the(target=target) @@ -57,7 +57,7 @@ def describe(self: SelfList) -> str: return f"The list of {self.target}." @beat("{} lists off the {target}.") - def answered_by(self: SelfList, the_actor: Actor) -> ListType[WebElement]: + def answered_by(self: SelfList, the_actor: Actor) -> list[WebElement]: """Direct the Actor to rattle off the specified elements.""" return self.target.all_found_by(the_actor) diff --git a/screenpy_selenium/questions/number.py b/screenpy_selenium/questions/number.py index 5b47fa6..20c3976 100644 --- a/screenpy_selenium/questions/number.py +++ b/screenpy_selenium/questions/number.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Type, TypeVar +from typing import TYPE_CHECKING, TypeVar from screenpy.pacing import beat @@ -26,7 +26,7 @@ class Number: """ @classmethod - def of(cls: Type[SelfNumber], target: Target) -> SelfNumber: + def of(cls: type[SelfNumber], target: Target) -> SelfNumber: """Target the element to be counted.""" return cls(target=target) diff --git a/screenpy_selenium/questions/selected.py b/screenpy_selenium/questions/selected.py index 0168935..026f36f 100644 --- a/screenpy_selenium/questions/selected.py +++ b/screenpy_selenium/questions/selected.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Type, TypeVar, Union +from typing import TYPE_CHECKING, TypeVar from screenpy.pacing import beat from selenium.webdriver.support.ui import Select as SeleniumSelect @@ -34,7 +34,7 @@ class Selected: multi: bool @classmethod - def option_from_the(cls: Type[SelfSelected], target: Target) -> SelfSelected: + def option_from_the(cls: type[SelfSelected], target: Target) -> SelfSelected: """ Get the option. @@ -50,13 +50,13 @@ def option_from_the(cls: Type[SelfSelected], target: Target) -> SelfSelected: return cls(target=target) @classmethod - def option_from(cls: Type[SelfSelected], target: Target) -> SelfSelected: + def option_from(cls: type[SelfSelected], target: Target) -> SelfSelected: """Alias of :meth:`~screenpy_selenium.actions.Selected.option_from_the`.""" return cls.option_from_the(target=target) @classmethod def options_from_the( - cls: Type[SelfSelected], multiselect_target: Target + cls: type[SelfSelected], multiselect_target: Target ) -> SelfSelected: """ Get all the options that are currently selected in a multi-select field. @@ -72,7 +72,7 @@ def options_from_the( @classmethod def options_from( - cls: Type[SelfSelected], multiselect_target: Target + cls: type[SelfSelected], multiselect_target: Target ) -> SelfSelected: """Alias of :meth:`~screenpy_selenium.actions.Selected.options_from_the`.""" return cls.options_from_the(multiselect_target=multiselect_target) @@ -82,7 +82,7 @@ def describe(self: SelfSelected) -> str: return f"The selected option(s) from the {self.target}." @beat("{} checks the selected option(s) from the {target}.") - def answered_by(self: SelfSelected, the_actor: Actor) -> Union[str, List[str]]: + def answered_by(self: SelfSelected, the_actor: Actor) -> str | list[str]: """Direct the Actor to name the selected option(s).""" select = SeleniumSelect(self.target.found_by(the_actor)) diff --git a/screenpy_selenium/questions/text.py b/screenpy_selenium/questions/text.py index 87d80af..5e9eab5 100644 --- a/screenpy_selenium/questions/text.py +++ b/screenpy_selenium/questions/text.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, List, Type, TypeVar, Union +from typing import TYPE_CHECKING, TypeVar from screenpy.pacing import beat @@ -35,7 +35,7 @@ class Text: multi: bool @classmethod - def of_the(cls: Type[SelfText], target: Target) -> SelfText: + def of_the(cls: type[SelfText], target: Target) -> SelfText: """Target the element to extract the text from. Aliases: @@ -45,17 +45,17 @@ def of_the(cls: Type[SelfText], target: Target) -> SelfText: return cls(target=target) @classmethod - def of(cls: Type[SelfText], target: Target) -> SelfText: + def of(cls: type[SelfText], target: Target) -> SelfText: """Alias of :meth:`~screenpy_selenium.actions.Text.of_the`.""" return cls.of_the(target=target) @classmethod - def of_the_first_of_the(cls: Type[SelfText], target: Target) -> SelfText: + def of_the_first_of_the(cls: type[SelfText], target: Target) -> SelfText: """Alias of :meth:`~screenpy_selenium.actions.Text.of_the`.""" return cls.of_the(target=target) @classmethod - def of_all(cls: Type[SelfText], multi_target: Target) -> SelfText: + def of_all(cls: type[SelfText], multi_target: Target) -> SelfText: """Target the elements, plural, to extract the text from.""" return cls(target=multi_target, multi=True) @@ -64,7 +64,7 @@ def describe(self: SelfText) -> str: return f"The text from the {self.target}." @beat("{} reads the text from the {target}.") - def answered_by(self: SelfText, the_actor: Actor) -> Union[str, List[str]]: + def answered_by(self: SelfText, the_actor: Actor) -> str | list[str]: """Direct the Actor to read off the text of the element(s).""" if self.multi: return [e.text for e in self.target.all_found_by(the_actor)] diff --git a/screenpy_selenium/resolutions/custom_matchers/is_clickable_element.py b/screenpy_selenium/resolutions/custom_matchers/is_clickable_element.py index a3c755b..7d57a16 100644 --- a/screenpy_selenium/resolutions/custom_matchers/is_clickable_element.py +++ b/screenpy_selenium/resolutions/custom_matchers/is_clickable_element.py @@ -20,7 +20,7 @@ class IsClickableElement(BaseMatcher[Optional[WebElement]]): """Matches an element which both ``is_enabled`` and ``is_displayed``.""" - def _matches(self, item: Optional[WebElement]) -> bool: + def _matches(self, item: WebElement | None) -> bool: if item is None: return False return item.is_displayed() and item.is_enabled() @@ -30,13 +30,13 @@ def describe_to(self, description: Description) -> None: description.append_text("the element is enabled/clickable") def describe_match( - self, _: Optional[WebElement], match_description: Description + self, _: WebElement | None, match_description: Description ) -> None: """Describe the matching case.""" match_description.append_text("it was enabled/clickable") def describe_mismatch( - self, item: Optional[WebElement], mismatch_description: Description + self, item: WebElement | None, mismatch_description: Description ) -> None: """Describe the failing case.""" if item is None or not item.is_displayed(): diff --git a/screenpy_selenium/resolutions/custom_matchers/is_invisible_element.py b/screenpy_selenium/resolutions/custom_matchers/is_invisible_element.py index 68e3b2a..f9871e9 100644 --- a/screenpy_selenium/resolutions/custom_matchers/is_invisible_element.py +++ b/screenpy_selenium/resolutions/custom_matchers/is_invisible_element.py @@ -20,7 +20,7 @@ class IsInvisibleElement(BaseMatcher[Optional[WebElement]]): """Matches an element whose ``is_displayed`` method returns False.""" - def _matches(self, item: Optional[WebElement]) -> bool: + def _matches(self, item: WebElement | None) -> bool: if item is None: return True return item.is_displayed() is False @@ -30,13 +30,13 @@ def describe_to(self, description: Description) -> None: description.append_text("the element is invisible") def describe_match( - self, _: Optional[WebElement], match_description: Description + self, _: WebElement | None, match_description: Description ) -> None: """Describe the matching case.""" match_description.append_text("it was invisible") def describe_mismatch( - self, _: Optional[WebElement], mismatch_description: Description + self, _: WebElement | None, mismatch_description: Description ) -> None: """Describe the failing case.""" mismatch_description.append_text("was not invisible") diff --git a/screenpy_selenium/resolutions/custom_matchers/is_present_element.py b/screenpy_selenium/resolutions/custom_matchers/is_present_element.py index dd185ea..3c977ba 100644 --- a/screenpy_selenium/resolutions/custom_matchers/is_present_element.py +++ b/screenpy_selenium/resolutions/custom_matchers/is_present_element.py @@ -20,7 +20,7 @@ class IsPresentElement(BaseMatcher[Optional[WebElement]]): """Matches an element to be a present WebElement.""" - def _matches(self, item: Optional[WebElement]) -> bool: + def _matches(self, item: WebElement | None) -> bool: if item is None: return False return isinstance(item, WebElement) @@ -30,13 +30,13 @@ def describe_to(self, description: Description) -> None: description.append_text("the element is present") def describe_match( - self, _: Optional[WebElement], match_description: Description + self, _: WebElement | None, match_description: Description ) -> None: """Describe the matching case.""" match_description.append_text("it was present") def describe_mismatch( - self, _: Optional[WebElement], mismatch_description: Description + self, _: WebElement | None, mismatch_description: Description ) -> None: """Describe the failing case.""" mismatch_description.append_text("was not present") diff --git a/screenpy_selenium/resolutions/custom_matchers/is_visible_element.py b/screenpy_selenium/resolutions/custom_matchers/is_visible_element.py index b87b557..b4188ba 100644 --- a/screenpy_selenium/resolutions/custom_matchers/is_visible_element.py +++ b/screenpy_selenium/resolutions/custom_matchers/is_visible_element.py @@ -20,7 +20,7 @@ class IsVisibleElement(BaseMatcher[Optional[WebElement]]): """Matches an element whose ``is_displayed`` method returns True.""" - def _matches(self, item: Optional[WebElement]) -> bool: + def _matches(self, item: WebElement | None) -> bool: if item is None: return False return item.is_displayed() @@ -30,13 +30,13 @@ def describe_to(self, description: Description) -> None: description.append_text("the element is visible") def describe_match( - self, _: Optional[WebElement], match_description: Description + self, _: WebElement | None, match_description: Description ) -> None: """Describe the matching case.""" match_description.append_text("it was visible") def describe_mismatch( - self, item: Optional[WebElement], mismatch_description: Description + self, item: WebElement | None, mismatch_description: Description ) -> None: """Describe the failing case.""" if item is None: diff --git a/screenpy_selenium/target.py b/screenpy_selenium/target.py index 2396002..aefe684 100644 --- a/screenpy_selenium/target.py +++ b/screenpy_selenium/target.py @@ -8,7 +8,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Iterator, List, Optional, Tuple, Type, TypeVar, Union +from typing import TYPE_CHECKING, Iterator, TypeVar from selenium.common.exceptions import WebDriverException from selenium.webdriver.common.by import By @@ -38,11 +38,11 @@ class Target: Target().located_by((By.ID, "username-field")) """ - _description: Optional[str] = None - locator: Optional[Tuple[str, str]] = None + _description: str | None = None + locator: tuple[str, str] | None = None @property - def target_name(self: SelfTarget) -> Optional[str]: + def target_name(self: SelfTarget) -> str | None: """Return the description when set or the 2nd half of the locator.""" if self._description is not None: return self._description @@ -57,16 +57,14 @@ def target_name(self: SelfTarget) -> None: del self._description @classmethod - def the(cls: Type[SelfTarget], desc: str) -> SelfTarget: + def the(cls: type[SelfTarget], desc: str) -> SelfTarget: """Name this Target. Beginning with a lower-case letter makes the logs look the nicest. """ return cls(desc=desc) - def located_by( - self: SelfTarget, locator: Union[Tuple[str, str], str] - ) -> SelfTarget: + def located_by(self: SelfTarget, locator: tuple[str, str] | str) -> SelfTarget: """Set the locator for this Target. Possible values for locator: @@ -93,11 +91,11 @@ def located_by( return self - def located(self: SelfTarget, locator: Union[Tuple[str, str], str]) -> SelfTarget: + def located(self: SelfTarget, locator: tuple[str, str] | str) -> SelfTarget: """Alias for :meth:~screenpy_selenium.Target.located_by.""" return self.located_by(locator) - def get_locator(self: SelfTarget) -> Tuple[str, str]: + def get_locator(self: SelfTarget) -> tuple[str, str]: """Return the stored locator. Raises: @@ -120,7 +118,7 @@ def found_by(self: SelfTarget, the_actor: Actor) -> WebElement: msg = f"{e} raised while trying to find {self}." raise TargetingError(msg) from e - def all_found_by(self: SelfTarget, the_actor: Actor) -> List[WebElement]: + def all_found_by(self: SelfTarget, the_actor: Actor) -> list[WebElement]: """Retrieve a list of |WebElement| objects as viewed by the Actor.""" browser = the_actor.ability_to(BrowseTheWeb).browser try: @@ -145,8 +143,8 @@ def __getitem__(self: SelfTarget, index: int) -> str: def __init__( self: SelfTarget, - desc: Optional[str] = None, - locator: Optional[Tuple[str, str]] = None, + desc: str | None = None, + locator: tuple[str, str] | None = None, ) -> None: self.target_name = desc self.locator = locator diff --git a/setup.py b/setup.py index 7c6c6f8..efcc520 100644 --- a/setup.py +++ b/setup.py @@ -11,10 +11,10 @@ repo_dir = path.abspath(path.dirname(__file__)) about = {} -with open(path.join(repo_dir, "screenpy_selenium", "__version__.py"), "r") as f: +with open(path.join(repo_dir, "screenpy_selenium", "__version__.py")) as f: exec(f.read(), about) -with open("README.md", "r") as f: +with open("README.md") as f: readme = f.read() setup( diff --git a/tests/test_questions.py b/tests/test_questions.py index d7474f0..6517afd 100644 --- a/tests/test_questions.py +++ b/tests/test_questions.py @@ -170,7 +170,7 @@ def test_caught_exception_annotation(self) -> None: e = Element(TARGET) annotation = e.__annotations__["caught_exception"] - assert annotation == "Optional[TargetingError]" + assert annotation == "TargetingError | None" def test_question_returns_none_if_no_element_found(self, Tester: Actor) -> None: test_target = Target.the("foo").located_by("//bar") diff --git a/tests/useful_mocks.py b/tests/useful_mocks.py index 69ac492..10a3892 100644 --- a/tests/useful_mocks.py +++ b/tests/useful_mocks.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Tuple, cast +from typing import TYPE_CHECKING, cast from unittest import mock from selenium.webdriver.common.action_chains import ActionChains @@ -29,7 +29,7 @@ def __new__(cls, *args: object, **kwargs: object) -> FakeTarget: # noqa: ARG003 return FakeTarget -def get_mocked_target_and_element() -> Tuple[mock.Mock, mock.Mock]: +def get_mocked_target_and_element() -> tuple[mock.Mock, mock.Mock]: """Get a mocked target which returns a mocked element.""" target = get_mock_target_class()() element = get_mocked_element()