Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/test_suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ jobs:
- name: UnitTest - Python-${{ matrix.python-version }}-${{ matrix.browser }}
run: |
pip install -e .[test]
pytest -n 5 -sqvv --browser=${{ matrix.browser }} --headless testing/test_foo.py testing/test_locator.py --cov=src --cov-report=xml
cd testing
pytest -n 5 -sqvv --browser=${{ matrix.browser }} --headless test_xpath.py test_version.py test_widget_descriptor.py test_version_pick.py test_fillable.py test_utils.py test_log.py test_browser.py test_locator.py --cov=src --cov-report=xml

# - name: Upload coverage to Codecov
# uses: codecov/codecov-action@v4
Expand Down
1,383 changes: 633 additions & 750 deletions src/widgetastic/browser.py

Large diffs are not rendered by default.

46 changes: 32 additions & 14 deletions src/widgetastic/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,60 @@
from selenium.common.exceptions import ElementNotInteractableException
from selenium.common.exceptions import MoveTargetOutOfBoundsException
from selenium.common.exceptions import NoAlertPresentException
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import StaleElementReferenceException
from selenium.common.exceptions import UnexpectedAlertPresentException
from selenium.common.exceptions import WebDriverException
"""
Widgetastic Core Exceptions
===========================
"""


class WidgetasticException(Exception):
"""A base exception for the widgetastic framework."""

pass


class LocatorNotImplemented(NotImplementedError, WidgetasticException):
"""Raised when a widget does not have a locator defined."""

pass


class WidgetOperationFailed(WidgetasticException):
"""Raised when an action on a widget does not result in the expected outcome."""

pass


class DoNotReadThisWidget(WidgetasticException):
"""
An exception that can be raised from a widget's read() method to signal
that it should not be included in the results of a view.read().
"""

pass


class RowNotFound(IndexError, WidgetasticException):
"""Raised when a table row cannot be found."""

pass


class NoSuchElementException(WidgetasticException):
"""Raised when an element cannot be found."""

pass


class NoAlertPresentException(WidgetasticException):
"""Raised when an action is attempted on an alert that is not present."""

pass


__all__ = [
"ElementNotInteractableException",
"MoveTargetOutOfBoundsException",
"NoAlertPresentException",
"NoSuchElementException",
"StaleElementReferenceException",
"UnexpectedAlertPresentException",
"WebDriverException",
"WidgetasticException",
"LocatorNotImplemented",
"WidgetOperationFailed",
"DoNotReadThisWidget",
"RowNotFound",
"NoSuchElementException",
"NoAlertPresentException",
]
5 changes: 4 additions & 1 deletion src/widgetastic/locator.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ def __locator__(self):

import re
from collections import namedtuple
from typing import Any, Optional, Tuple, TYPE_CHECKING
from typing import Any
from typing import Optional
from typing import Tuple
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from typing import Type
Expand Down
2 changes: 1 addition & 1 deletion src/widgetastic/ouia/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def is_safe(self) -> bool:
An attribute called data-ouia-safe, which is True only when the component is in a static
state, i.e. no animations are occurring. At all other times, this value MUST be False.
"""
return "true" in self.browser.get_attribute("data-ouia-safe", self)
return "true" == self.browser.get_attribute("data-ouia-safe", self)

def __locator__(self) -> ParametrizedLocator:
return self.ROOT
Expand Down
14 changes: 10 additions & 4 deletions src/widgetastic/types.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
"""
Widgetastic Core Type Declarations
==================================
"""

from typing import Callable
from typing import Dict
from typing import List
Expand All @@ -6,9 +11,10 @@
from typing import TYPE_CHECKING
from typing import Union

from selenium.webdriver.remote.webelement import WebElement
from smartloc import Locator
from playwright.sync_api import ElementHandle
from playwright.sync_api import Locator

from .locator import SmartLocator

if TYPE_CHECKING:
from .browser import Browser
Expand All @@ -21,10 +27,10 @@
class LocatorProtocol(Protocol):
CHECK_VISIBILITY: bool

def __locator__(self) -> Union[str, Locator, WebElement]: ...
def __locator__(self) -> Union[str, SmartLocator, Locator, ElementHandle]: ...


LocatorAlias = Union[str, Dict[str, str], WebElement, LocatorProtocol, "Widget"]
LocatorAlias = Union[str, Dict[str, str], Locator, ElementHandle, LocatorProtocol, "Widget"]

ElementParent = Union[LocatorAlias, "Browser"]

Expand Down
Loading