selenium_automation_project/page_objects/dynamic_content_page.py

107 lines
4.1 KiB
Python

import time
from selenium.webdriver.common.by import By
from .base_page import BasePage
class DynamicContentPage(BasePage):
"""
Page Object for the Dynamic Content test page.
"""
# --- Locators ---
_DELAYED_TEXT = (By.ID, "delayed-text")
_ENABLE_BUTTON = (By.XPATH, "//button[text()='Enable Button']")
_INITIALLY_DISABLED_BUTTON = (By.XPATH, "//button[text()='Initially Disabled']")
By.XPATH, '//*[@id="radix-«r0»-trigger-password"]'
_ACCOUNT_TAB = (By.XPATH, "//button[@role='tab' and contains(@id,'trigger-account')]")
_PASSWORD_TAB = (By.XPATH, "//button[@role='tab' and contains(@id,'trigger-password')]")
_ACTIVE_TAB_CONTENT = (By.XPATH, "//div[@role='tabpanel' and @data-state='active']")
_SHOW_ALERT_BUTTON = (By.XPATH, "//button[text()='Show Alert']")
_OPEN_MODAL_BUTTON = (By.XPATH, "//button[text()='Open Modal']")
_MODAL_TITLE = (By.ID, "radix-") # This ID is dynamic, a better locator is needed.
# A better locator for the modal title would be:
_MODAL_TITLE_BETTER = (By.XPATH, "//h2[text()='Modal Title']")
def __init__(self, driver):
"""Initializes the DynamicContentPage with the WebDriver."""
super().__init__(driver)
self.page_path = "/dynamic-content"
# --- Page Actions ---
def open(self, base_url: str):
"""Navigates to the dynamic content page."""
super().open(base_url, self.page_path)
def get_delayed_text(self) -> str:
"""
Waits for the delayed text to be visible and returns its content.
The wait is handled by find_visible_element.
"""
# We need to wait for the text "Loading..." to disappear first.
# This is a more complex wait condition. For simplicity, we'll just wait for visibility.
time.sleep(4)
element = self.find_visible_element(self._DELAYED_TEXT)
return element.text
def click_enable_button(self):
"""Clicks the button that enables the initially disabled button."""
self.click(self._ENABLE_BUTTON)
def is_initially_disabled_button_enabled(self) -> bool:
"""Checks if the initially disabled button is now enabled."""
return self.is_element_enabled(self._INITIALLY_DISABLED_BUTTON)
def switch_to_tab(self, tab_name: str):
"""
Switches to the specified tab.
:param tab_name: 'account' or 'password'.
"""
if tab_name.lower() == 'account':
self.click(self._ACCOUNT_TAB)
elif tab_name.lower() == 'password':
self.click(self._PASSWORD_TAB)
else:
raise ValueError("Invalid tab name. Must be 'account' or 'password'.")
time.sleep(1) # Add a short delay to allow the tab content to update
def get_active_tab_content(self) -> str:
"""
Gets the text of the currently visible tab panel.
This requires checking which panel is visible.
"""
element = self.find_visible_element(self._ACTIVE_TAB_CONTENT)
return element.text
# def get_active_tab_content(self) -> str:
# """
# Gets the text of the currently active tab panel based on hidden attribute.
# """
# panels = [self._ACCOUNT_TAB_CONTENT, self._PASSWORD_TAB_CONTENT]
# for panel in panels:
# element = self.find_element(panel)
# if element.get_attribute("hidden") in [None, "false"]:
# return element.text
# return ""
def trigger_alert(self):
"""Clicks the button to show a browser alert."""
self.click(self._SHOW_ALERT_BUTTON)
def get_alert_text_and_accept(self) -> str:
"""Switches to an alert, gets its text, and accepts it."""
alert = self.switch_to_alert()
text = alert.text
alert.accept()
return text
def open_modal(self):
"""Clicks the button to open the modal dialog."""
self.click(self._OPEN_MODAL_BUTTON)
def get_modal_title(self) -> str:
"""Waits for the modal to be visible and returns its title."""
# Using the more robust locator
title_element = self.find_visible_element(self._MODAL_TITLE_BETTER)
return title_element.text