Coverage for src / ocarina / pom / base.py: 100.00%

7 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-06-04 15:56 +0200

1"""Page Object Model base class. 

2 

3This module defines POMBase, the universal abstract base class for all 

4page objects, independent of browser automation framework. 

5 

6The POM pattern encapsulates: 

7- Page verification (verify() method) 

8- Page actions (methods to interact with elements) 

9- Page elements (locators, element references) 

10 

11POMBase provides a minimal, framework-agnostic interface that works with 

12Selenium, Playwright, Puppeteer, or any other browser automation tool. 

13 

14Example: 

15 >>> class LoginPage(POMBase): 

16 ... def __init__(self, driver: WebDriver): 

17 ... self._driver = driver 

18 ... 

19 ... def verify(self, timeout: float | None = None) -> Self: 

20 ... WebDriverWait(self._driver, timeout or 10).until( 

21 ... EC.presence_of_element_located((By.ID, "login-form")) 

22 ... ) 

23 ... return self 

24 ... 

25 ... def enter_username(self, username: str) -> Self: 

26 ... self._driver.find_element(By.ID, "username").send_keys(username) 

27 ... return self 

28 

29""" 

30 

31from abc import ABC, abstractmethod 

32from typing import Self 

33 

34 

35class POMBase(ABC): 

36 """Abstract base class for Page Object Model. 

37 

38 Defines the universal contract all page objects must follow, regardless 

39 of the underlying browser automation framework (Selenium, Playwright, etc.). 

40 

41 The only required method is verify(), which checks that the browser is 

42 on the expected page. All other page-specific functionality (actions, 

43 element access, etc.) is left to concrete implementations. 

44 

45 Subclassing guidelines: 

46 - Implement verify() with page-specific checks 

47 - Return Self from methods for fluent API 

48 - Raise appropriate exceptions on verification failure 

49 - Store driver/page instance as needed by framework 

50 

51 Example (Selenium): 

52 >>> class LoginPage(POMBase): 

53 ... def __init__(self, driver: WebDriver): 

54 ... self._driver = driver 

55 ... 

56 ... def verify(self, timeout: float | None = None) -> Self: 

57 ... WebDriverWait(self._driver, timeout or 10).until( 

58 ... EC.presence_of_element_located((By.ID, "login-form")) 

59 ... ) 

60 ... return self 

61 

62 """ 

63 

64 @abstractmethod 

65 def verify(self, *, timeout: float | None = None) -> Self: 

66 """Verify that the browser is on the expected page. 

67 

68 Checks for page-specific indicators such as unique elements, URL 

69 patterns, or page content. This method is typically called after 

70 navigation or page transitions to confirm the correct page loaded. 

71 

72 Args: 

73 timeout: Maximum seconds to wait for verification. If None, 

74 implementations should use a sensible default (typically 10s). 

75 

76 Returns: 

77 Self for method chaining. 

78 

79 Raises: 

80 Implementation-specific exceptions when verification fails 

81 (e.g., TimeoutException, PageVerificationError). 

82 

83 Example: 

84 >>> def verify(self, timeout: float | None = None) -> Self: 

85 ... WebDriverWait(self._driver, timeout or 10).until( 

86 ... EC.presence_of_element_located((By.ID, "unique-element")) 

87 ... ) 

88 ... return self 

89 

90 """ 

91 ... 

92 

93 @abstractmethod 

94 def get_current_title(self) -> str: 

95 """Get the current page title (empty string if no <title>).""" 

96 ...