Cursor rule
example-structures/selenium-python/.cursor/rules/page-object-patterns.mdcPage Object Model patterns for Selenium — BasePage, component objects, and fluent interfaces
Cursor rules
Quality
54/100
Scores the file, not the repository.Length
669 words
5 headings · 3 code blocksRepository
18
— · pushed 0 days agoLast changed
2 days ago
First indexed 2 days ago.123456# Page Object Model Excellence78## Advanced POM Architecture9- **Inheritance Hierarchy**: BasePage class with common functionality10- **Component Pattern**: Reusable UI components across pages11- **Fluent Interface**: Method chaining for readable test code12- **Smart Locators**: Dynamic locator strategies with fallbacks1314## Base Page Implementation15```python16from typing import Optional, List, Union, Tuple17from selenium.webdriver.remote.webelement import WebElement18from selenium.webdriver.support.ui import WebDriverWait19from selenium.webdriver.support import expected_conditions as EC20from selenium.webdriver.common.by import By21from selenium.webdriver.common.action_chains import ActionChains22from selenium.common.exceptions import TimeoutException, StaleElementReferenceException23import logging2425logger = logging.getLogger(__name__)2627class BasePage:28 """Enhanced base page with advanced interaction methods."""2930 def __init__(self, driver, timeout: int = 10):31 self.driver = driver32 self.wait = WebDriverWait(driver, timeout)33 self.timeout = timeout34 self.actions = ActionChains(driver)3536 def find_element_safely(self, locator: Tuple[str, str], timeout: Optional[int] = None) -> Optional[WebElement]:37 """Find element with comprehensive error handling and retry logic."""38 timeout = timeout or self.timeout39 wait = WebDriverWait(self.driver, timeout)4041 try:42 element = wait.until(EC.presence_of_element_located(locator))43 logger.debug(f"Element found successfully: {locator}")44 return element45 except TimeoutException:46 logger.warning(f"Element not found within {timeout}s: {locator}")47 return None48 except StaleElementReferenceException:49 logger.warning(f"Stale element detected, retrying: {locator}")50 return self.find_element_safely(locator, timeout)5152 def click_when_clickable(self, locator: Tuple[str, str], timeout: Optional[int] = None) -> bool:53 """Click element only when it's clickable with retry logic."""54 timeout = timeout or self.timeout55 wait = WebDriverWait(self.driver, timeout)5657 try:58 element = wait.until(EC.element_to_be_clickable(locator))5960 # Scroll element into view before clicking61 self.driver.execute_script("arguments[0].scrollIntoView(true);", element)6263 # Use Actions for more reliable clicking64 self.actions.move_to_element(element).click().perform()65 logger.info(f"Successfully clicked element: {locator}")66 return True67 except TimeoutException:68 logger.error(f"Element not clickable: {locator}")69 return False70 except Exception as e:71 logger.error(f"Click failed for {locator}: {str(e)}")72 return False7374 def enter_text_safely(self, locator: Tuple[str, str], text: str,75 clear_first: bool = True, validate: bool = True) -> bool:76 """Enter text with validation and error handling."""77 element = self.find_element_safely(locator)78 if not element:79 return False8081 try:82 # Scroll to element and focus83 self.driver.execute_script("arguments[0].scrollIntoView(true);", element)84 element.click() # Focus the element8586 if clear_first:87 element.clear()8889 element.send_keys(text)9091 # Verify text was entered correctly if validation is enabled92 if validate:93 entered_value = element.get_attribute('value')94 if entered_value == text:95 logger.info(f"Text entered successfully: '{text}' in {locator}")96 return True97 else:98 logger.warning(f"Text entry verification failed. Expected: '{text}', Got: '{entered_value}'")99 return False100101 logger.info(f"Text entered (no validation): '{text}' in {locator}")102 return True103104 except Exception as e:105 logger.error(f"Failed to enter text in {locator}: {str(e)}")106 return False107```108109## Example Page Implementation110```python111class LoginPage(BasePage):112 """Login page with comprehensive functionality."""113114 def __init__(self, driver):115 super().__init__(driver)116 self.url = "/login"117118 # Locators119 self.email_input = (By.ID, "email")120 self.password_input = (By.ID, "password")121 self.login_button = (By.CSS_SELECTOR, "[data-cy=login-button]")122 self.error_message = (By.CSS_SELECTOR, "[data-cy=error-message]")123 self.forgot_password_link = (By.CSS_SELECTOR, "[data-cy=forgot-password]")124 self.remember_me_checkbox = (By.CSS_SELECTOR, "[data-cy=remember-me]")125126 def navigate(self) -> 'LoginPage':127 """Navigate to login page with fluent interface."""128 self.driver.get(self.url)129 self.wait_for_page_load()130 return self131132 def wait_for_page_load(self) -> bool:133 """Wait for login page to be fully loaded."""134 return (self.wait_for_element_visible(self.email_input) and135 self.wait_for_element_visible(self.password_input))136137 def enter_email(self, email: str) -> 'LoginPage':138 """Enter email with fluent interface."""139 self.enter_text_safely(self.email_input, email)140 return self141142 def enter_password(self, password: str) -> 'LoginPage':143 """Enter password with fluent interface."""144 self.enter_text_safely(self.password_input, password)145 return self146147 def check_remember_me(self) -> 'LoginPage':148 """Check remember me checkbox."""149 self.click_when_clickable(self.remember_me_checkbox)150 return self151152 def click_login(self) -> Union['DashboardPage', 'LoginPage']:153 """Click login button and return appropriate page object."""154 if self.click_when_clickable(self.login_button):155 # Wait for navigation or error156 if self.wait_for_element_invisible(self.login_button, timeout=5):157 from pages.dashboard_page import DashboardPage158 return DashboardPage(self.driver)159 elif self.is_element_present(self.error_message):160 return self # Stay on login page if error161 return self162163 def login(self, email: str, password: str, remember_me: bool = False) -> Union['DashboardPage', 'LoginPage']:164 """Complete login flow with method chaining."""165 login_chain = self.enter_email(email).enter_password(password)166167 if remember_me:168 login_chain = login_chain.check_remember_me()169170 return login_chain.click_login()171```172173## Component-Based Architecture174```python175class BaseComponent:176 """Base class for reusable UI components."""177178 def __init__(self, driver, root_locator: Tuple[str, str]):179 self.driver = driver180 self.root_locator = root_locator181 self.base_page = BasePage(driver)182183 def is_displayed(self) -> bool:184 """Check if component is displayed."""185 return self.base_page.wait_for_element_visible(self.root_locator, timeout=5)186187 def wait_for_component(self, timeout: int = 10) -> bool:188 """Wait for component to be visible."""189 return self.base_page.wait_for_element_visible(self.root_locator, timeout)190191class NavigationComponent(BaseComponent):192 """Reusable navigation component."""193194 def __init__(self, driver):195 super().__init__(driver, (By.CSS_SELECTOR, "[data-cy=main-navigation]"))196 self.menu_items = (By.CSS_SELECTOR, "[data-cy=nav-item]")197 self.user_menu = (By.CSS_SELECTOR, "[data-cy=user-menu]")198 self.logout_button = (By.CSS_SELECTOR, "[data-cy=logout]")199200 def navigate_to(self, menu_name: str) -> bool:201 """Navigate to specific menu item."""202 if not self.is_displayed():203 logger.error("Navigation component not displayed")204 return False205206 menu_locator = (By.CSS_SELECTOR, f"[data-cy=nav-{menu_name.lower()}]")207 return self.base_page.click_when_clickable(menu_locator)208209 def logout(self) -> bool:210 """Perform logout action."""211 if self.base_page.click_when_clickable(self.user_menu):212 return self.base_page.click_when_clickable(self.logout_button)213 return False214```215
Also in tugkanboz/awesome-cursorrules
Diff this repo’s formatsOne repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| tugkanboz/awesome-cursorrulesexample-structures/cypress/.cursor/rules/api-testing.mdc · 18 | Cursor rules | testtesting-strategyapi | 58/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/cypress/.cursor/rules/testing-fundamentals.mdc · 18 | Cursor rules | testarchtesting-strategysecurity+2 | 62/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/appium-mobile-test-automation-framework/.cursorrules · 18 | .cursorrules | teststylearchperformance+2 | 56/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/cypress-javascript-test-automation-framework/.cursorrules · 18 | .cursorrules | testlint-formatstylearch+4 | 59/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/k6-performance-test-framework/.cursorrules · 18 | .cursorrules | setupteststylearch+2 | 56/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/restassured-java-framework/.cursorrules · 18 | .cursorrules | teststylearchsecurity+4 | 56/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/selenium-net-test-automation-framework/.cursorrules · 18 | .cursorrules | teststylearchdeployment+1 | 56/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/selenium-python-test-automation-framework/.cursorrules · 18 | .cursorrules | testlint-formatstylearch+3 | 59/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/webdriverio-javascript-test-automation-framework/.cursorrules · 18 | .cursorrules | testlint-formatstylearch+4 | 69/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/next-js/.cursor/rules/app-router-patterns.mdc · 18 | Cursor rules | styleapido-not | 65/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/react-typescript/.cursor/rules/component-development.mdc · 18 | Cursor rules | teststylearchtypes+1 | 58/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/selenium-python/.cursor/rules/framework-architecture.mdc · 18 | Cursor rules | setuptestlint-formatstyle+3 | 93/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/selenium-python/.cursor/rules/test-patterns.mdc · 18 | Cursor rules | teststylearchtesting-strategy+1 | 66/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesframeworks/cypress/.cursor/rules/cypress-excellence.mdc · 18 | Cursor rules | testtesting-strategysecurityperformance+1 | 58/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/playwright-javascript-test-automation-framework/.cursorrules · 18 | .cursorrules | testlint-formatstylearch+3 | 59/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/vitest-javascript-unit-test-framework/.cursorrules · 18 | .cursorrules | setupteststylearch+5 | 60/100 | 2 days ago |
Diff against example-structures/cypress/.cursor/rules/api-testing.mdc Diff against example-structures/cypress/.cursor/rules/testing-fundamentals.mdc Diff against rules/appium-mobile-test-automation-framework/.cursorrules Diff against rules/cypress-javascript-test-automation-framework/.cursorrules Diff against rules/k6-performance-test-framework/.cursorrules Diff against rules/restassured-java-framework/.cursorrules Diff against rules/selenium-net-test-automation-framework/.cursorrules Diff against rules/selenium-python-test-automation-framework/.cursorrules Diff against rules/webdriverio-javascript-test-automation-framework/.cursorrules Diff against example-structures/next-js/.cursor/rules/app-router-patterns.mdc Diff against example-structures/react-typescript/.cursor/rules/component-development.mdc Diff against example-structures/selenium-python/.cursor/rules/framework-architecture.mdc Diff against example-structures/selenium-python/.cursor/rules/test-patterns.mdc Diff against frameworks/cypress/.cursor/rules/cypress-excellence.mdc Diff against rules/playwright-javascript-test-automation-framework/.cursorrules Diff against rules/vitest-javascript-unit-test-framework/.cursorrules
