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
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@

<br>

## v3.4.1
*Release date: 2026-03-27*

### Fixed
- Element.locator/locator_type/log_locator access without initialised driver

## v3.4.0 (Performance improvement)
*Release date: 2026-03-26*
*Release date: 2026-03-27*

### Breaking Changes
- **`Group` subclasses**: `parent` is now correctly set on sub-elements defined after `super().__init__()` —
Expand Down
2 changes: 1 addition & 1 deletion mops/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__version__ = '3.4.0'
__version__ = '3.4.1'
__project_name__ = 'mops'
6 changes: 3 additions & 3 deletions mops/base/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def __init_base_class__(self) -> None:

@property
def locator(self) -> str:
if not self._is_locator_configured:
if self.driver_wrapper and not self._is_locator_configured:
self._set_locator()

return self._locator
Expand All @@ -181,7 +181,7 @@ def locator(self, value: Union[Locator, str]) -> None:

@property
def locator_type(self) -> str:
if not self._is_locator_configured:
if self.driver_wrapper and not self._is_locator_configured:
self._set_locator()

return self._locator_type
Expand All @@ -192,7 +192,7 @@ def locator_type(self, value: str) -> None:

@property
def log_locator(self) -> str:
if not self._is_locator_configured:
if self.driver_wrapper and not self._is_locator_configured:
self._set_locator()

return self._log_locator
Expand Down
33 changes: 33 additions & 0 deletions tests/static_tests/integration/test_locator_without_driver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import pytest

from mops.base.element import Element
from mops.base.group import Group
from mops.base.page import Page
from mops.exceptions import DriverWrapperException

group = Group('some_group', name='test group')
element = Element('some_locator', name='test element')


@pytest.mark.parametrize('obj', [element, group], ids=['element', 'group'])
def test_locator_access_without_driver(obj):
assert obj.locator


@pytest.mark.parametrize('obj', [element, group], ids=['element', 'group'])
def test_locator_type_access_without_driver(obj):
assert obj.locator_type is None


@pytest.mark.parametrize('obj', [element, group], ids=['element', 'group'])
def test_log_locator_access_without_driver(obj):
assert obj.log_locator


def test_page_init_without_driver():
try:
Page('some_page', name='test page')
except DriverWrapperException as exc:
msg = ('Cannot initialize Page: unsupported driver type "NoneType". '
'Expected Playwright, Appium or Selenium driver instance')
assert msg == exc.msg
Loading