Page Objects¶
Page Objects keep selectors and common actions in one class. The standard scaffold generated by dolphin init creates a small Notepad Page Object.
Generated Example¶
objects/notepad_page.py
from __future__ import annotations
from dolphin_desktop._window import Window
class NotepadPage:
def __init__(self, window: Window) -> None:
self._win = window
self._editor = window.get_by_role("Document")
def type_text(self, text: str) -> "NotepadPage":
self._editor.click()
self._editor.type_text(text)
return self
def clear(self) -> "NotepadPage":
self._editor.clear()
return self
def read_text(self) -> str:
return self._editor.text()
The test imports and uses it:
tests/test_sample.py
import pytest
from objects.notepad_page import NotepadPage
pytestmark = pytest.mark.integration
def test_notepad_with_page_object(launch):
app = launch("notepad.exe")
win = app.window(class_name="Notepad")
page = NotepadPage(win)
page.type_text("Hello, Dolphin!")
assert "Hello, Dolphin!" in page.read_text()
Recommended Shape¶
Keep locator creation inside the class and expose user-level operations:
class LoginPage:
def __init__(self, window):
self._win = window
@property
def _username(self):
return self._win.get_by_automation_id("txtUsername")
@property
def _password(self):
return self._win.get_by_automation_id("txtPassword")
def sign_in(self, username: str, password: str) -> None:
self._username.set_text(username)
self._password.set_text(password)
self._win.get_by_role("Button", name="Sign in").click()
Using properties keeps locators lazy. Each action resolves the element against the current UI.
Project Layout¶
my-tests/
|-- objects/
| |-- __init__.py
| `-- notepad_page.py
`-- tests/
|-- __init__.py
`-- test_sample.py
Next: Fallback Selectors.