fix and add som usecases
This commit is contained in:
@@ -11,24 +11,23 @@ class BasePage:
|
||||
improve test maintenance.
|
||||
"""
|
||||
|
||||
def __init__(self, driver: WebDriver, base_url: str = "http://120.53.89.168:90"):
|
||||
def __init__(self, driver: WebDriver):
|
||||
"""
|
||||
Initializes the BasePage with a WebDriver instance and a base URL.
|
||||
Initializes the BasePage with a WebDriver instance.
|
||||
|
||||
:param driver: The WebDriver instance to interact with the browser.
|
||||
:param base_url: The base URL of the web application under test.
|
||||
"""
|
||||
self.driver = driver
|
||||
self.base_url = base_url
|
||||
self.wait = WebDriverWait(driver, 10) # Default explicit wait of 10 seconds
|
||||
|
||||
def open_url(self, path: str):
|
||||
def open(self, base_url: str, path: str):
|
||||
"""
|
||||
Navigates to a specific path relative to the base URL.
|
||||
|
||||
:param base_url: The base URL of the web application.
|
||||
:param path: The relative path to open (e.g., "/form-elements").
|
||||
"""
|
||||
url = self.base_url + path
|
||||
url = base_url.rstrip('/') + path
|
||||
self.driver.get(url)
|
||||
|
||||
def find_element(self, locator: tuple) -> WebElement:
|
||||
@@ -177,3 +176,12 @@ class BasePage:
|
||||
:return: True if the text is present, False otherwise.
|
||||
"""
|
||||
return self.wait.until(EC.text_to_be_present_in_element(locator, text))
|
||||
|
||||
def wait_for_url_contains(self, url_substring: str):
|
||||
"""
|
||||
Waits until the current URL contains the given substring.
|
||||
|
||||
:param url_substring: The substring to look for in the URL.
|
||||
:return: True if the URL contains the substring, False otherwise.
|
||||
"""
|
||||
return self.wait.until(EC.url_contains(url_substring))
|
||||
|
||||
56
page_objects/danger_zone_page.py
Normal file
56
page_objects/danger_zone_page.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from typing import Self
|
||||
from selenium.webdriver.common import by
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
|
||||
from page_objects.base_page import BasePage
|
||||
|
||||
class DangerZonePage(BasePage):
|
||||
"""
|
||||
Page object for the Danger Zone page.
|
||||
"""
|
||||
|
||||
# Locators
|
||||
DELETE_ACCOUNT_BUTTON = (By.XPATH, '/html/body/div/div/main/div/div[3]/div/div[2]/button')
|
||||
CONFIRM_DELETE_BUTTON = (By.XPATH, '/html/body/div[3]/div[3]/button')
|
||||
CANCEL_DELETE_BUTTON = (By.XPATH, '/html/body/div[3]/button')
|
||||
DIALOG_TITLE = (By.XPATH, '/html/body/div[3]/div[1]/h2') # Assuming dialog title
|
||||
DIALOG_INPUT = (By.XPATH,'/html/body/div[3]/div[2]/input')
|
||||
_DANGER_ZONE_TITLE = (By.XPATH,'//*[@id="root"]/div/main/div/div[3]/div/div[1]/h3')
|
||||
|
||||
def get_page_header(self):
|
||||
"""
|
||||
Gets the header text of the page.
|
||||
Assumes the header is an h1 element.
|
||||
"""
|
||||
return self.get_text((By.TAG_NAME, "h1"))
|
||||
|
||||
def click_delete_account(self):
|
||||
"""
|
||||
Clicks the 'Delete Account' button to open the confirmation dialog.
|
||||
"""
|
||||
self.click(self.DELETE_ACCOUNT_BUTTON)
|
||||
|
||||
def verify_confirmation_dialog_exist(self):
|
||||
return self.get_text(self.DIALOG_TITLE)
|
||||
|
||||
def set_dialog_input(self):
|
||||
self.send_keys(self.DIALOG_INPUT,'delete my account')
|
||||
return ''
|
||||
def click_cancel_in_dialog(self, timeout=5):
|
||||
"""
|
||||
Safely clicks the cancel button in the confirmation dialog.
|
||||
"""
|
||||
self.click(self.CANCEL_DELETE_BUTTON)
|
||||
|
||||
|
||||
|
||||
|
||||
def click_confirm_in_dialog(self):
|
||||
"""
|
||||
Clicks the 'Confirm' button within the confirmation dialog.
|
||||
"""
|
||||
self.click(self.CONFIRM_DELETE_BUTTON)
|
||||
|
||||
def verify_danger_zone_exist(self):
|
||||
return self.get_text(self._DANGER_ZONE_TITLE)
|
||||
@@ -29,9 +29,9 @@ class DynamicContentPage(BasePage):
|
||||
|
||||
# --- Page Actions ---
|
||||
|
||||
def open(self):
|
||||
def open(self, base_url: str):
|
||||
"""Navigates to the dynamic content page."""
|
||||
self.open_url(self.page_path)
|
||||
super().open(base_url, self.page_path)
|
||||
|
||||
def get_delayed_text(self) -> str:
|
||||
"""
|
||||
|
||||
@@ -28,9 +28,9 @@ class FormElementsPage(BasePage):
|
||||
|
||||
# --- Page Actions ---
|
||||
|
||||
def open(self):
|
||||
def open(self, base_url: str):
|
||||
"""Navigates to the form elements page."""
|
||||
self.open_url(self.page_path)
|
||||
super().open(base_url, self.page_path)
|
||||
|
||||
def enter_text_in_input(self, text: str):
|
||||
"""Enters text into the main text input field."""
|
||||
|
||||
34
page_objects/home_dashboard_page.py
Normal file
34
page_objects/home_dashboard_page.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from selenium.webdriver.common.by import By
|
||||
from page_objects.base_page import BasePage
|
||||
|
||||
class HomeDashboardPage(BasePage):
|
||||
"""
|
||||
Page object for the main Home/Dashboard page, specifically handling the top navigation.
|
||||
"""
|
||||
|
||||
# Locators
|
||||
_PROFILE_TAB = (By.XPATH, "//button[@role='tab' and contains(@id,'trigger-profile')]")
|
||||
_SETTINGS_TAB = (By.XPATH, "//button[@role='tab' and contains(@id,'trigger-settings')]")
|
||||
DANGER_ZONE_LINK = (By.LINK_TEXT, "Danger Zone")
|
||||
LOGOUT_BUTTON = (By.XPATH, "//button[text()='Logout']")
|
||||
_DASHBORAD_TEST_CASES_TITLE = (By.XPATH,'//*[contains(@id,"content-dashboard")]/div/div[1]//h3')
|
||||
|
||||
def navigate_to_profile(self):
|
||||
"""
|
||||
Clicks the 'Profile' link to navigate to the Profile Editor page.
|
||||
"""
|
||||
self.click(self._PROFILE_TAB)
|
||||
|
||||
def navigate_to_settings(self):
|
||||
"""
|
||||
Clicks the 'Settings' link to navigate to the Settings Panel page.
|
||||
"""
|
||||
self.click(self._SETTINGS_TAB)
|
||||
|
||||
def verify_title_is_dashboarde(self):
|
||||
return self.get_text(self._DASHBORAD_TEST_CASES_TITLE)
|
||||
def logout(self):
|
||||
"""
|
||||
Clicks the 'Logout' button.
|
||||
"""
|
||||
self.click(self.LOGOUT_BUTTON)
|
||||
@@ -0,0 +1,49 @@
|
||||
from selenium.webdriver.common.by import By
|
||||
from .base_page import BasePage
|
||||
|
||||
class HomePage(BasePage):
|
||||
"""
|
||||
Page Object for the Home page (Dashboard).
|
||||
"""
|
||||
|
||||
# --- Locators ---
|
||||
_WELCOME_MESSAGE = (By.XPATH, '//*[@id="root"]/div/main/div/div[1]/h1')
|
||||
_LOGOUT_BUTTON = (By.XPATH, "//button[text()='Logout']")
|
||||
_PROFILE_TAB = (By.XPATH, "//button[@role='tab' and text()='Profile']")
|
||||
_DASHBOARD_CONTENT = (By.XPATH, '/html/body/div/div/main/div/div[2]/div[2]/div')
|
||||
_DASHBORAD_TEST_CASES_TITLE = (By.XPATH,'//*[contains(@id,"content-dashboard")]/div/div[1]//h3')
|
||||
def __init__(self, driver):
|
||||
"""Initializes the HomePage with the WebDriver."""
|
||||
super().__init__(driver)
|
||||
self.page_path = "/" # The home page is at the root path after login
|
||||
|
||||
# --- Page Actions ---
|
||||
|
||||
def open(self, base_url: str):
|
||||
"""Navigates to the home page."""
|
||||
super().open(base_url, self.page_path)
|
||||
|
||||
def get_welcome_message(self) -> str:
|
||||
"""
|
||||
Gets the welcome message text from the page header.
|
||||
"""
|
||||
try:
|
||||
return self.find_visible_element(self._WELCOME_MESSAGE).text
|
||||
except:
|
||||
return ""
|
||||
|
||||
def is_dashboard_content_visible(self) -> bool:
|
||||
"""
|
||||
Checks if the main dashboard content area is visible.
|
||||
"""
|
||||
return self.get_text(self._DASHBORAD_TEST_CASES_TITLE) == 'Test Cases'
|
||||
|
||||
def switch_to_profile_tab(self):
|
||||
"""
|
||||
Clicks the 'Profile' tab to switch to the profile view.
|
||||
"""
|
||||
self.click(self._PROFILE_TAB)
|
||||
|
||||
def click_logout_button(self):
|
||||
"""Clicks the logout button."""
|
||||
self.click(self._LOGOUT_BUTTON)
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
from selenium.webdriver.common.by import By
|
||||
from .base_page import BasePage
|
||||
|
||||
class LoginPage(BasePage):
|
||||
"""
|
||||
Page Object for the Login page.
|
||||
"""
|
||||
|
||||
# --- Locators ---
|
||||
_EMAIL_INPUT = (By.ID, "email")
|
||||
_PASSWORD_INPUT = (By.ID, "password")
|
||||
_SIGN_IN_BUTTON = (By.XPATH, "//button[@type='submit']")
|
||||
_ERROR_MESSAGE = (By.XPATH, "//p[contains(@class, 'text-red-500')]")
|
||||
_LOGIN_FORM = (By.XPATH, "//form")
|
||||
|
||||
def __init__(self, driver):
|
||||
"""Initializes the LoginPage with the WebDriver."""
|
||||
super().__init__(driver)
|
||||
self.page_path = "/login"
|
||||
|
||||
# --- Page Actions ---
|
||||
|
||||
def open(self, base_url: str):
|
||||
"""Navigates to the login page."""
|
||||
super().open(base_url, self.page_path)
|
||||
|
||||
def enter_email(self, email: str):
|
||||
"""Enters the email into the email input field."""
|
||||
self.send_keys(self._EMAIL_INPUT, email)
|
||||
|
||||
def enter_password(self, password: str):
|
||||
"""Enters the password into the password input field."""
|
||||
self.send_keys(self._PASSWORD_INPUT, password)
|
||||
|
||||
def click_sign_in(self):
|
||||
"""Clicks the 'Sign in' button."""
|
||||
self.click(self._SIGN_IN_BUTTON)
|
||||
|
||||
def login(self, email: str, password: str):
|
||||
"""Performs a full login action."""
|
||||
self.enter_email(email)
|
||||
self.enter_password(password)
|
||||
self.click_sign_in()
|
||||
|
||||
def get_error_message(self) -> str:
|
||||
"""
|
||||
Waits for the error message to be visible and returns its text.
|
||||
Returns an empty string if the message is not found.
|
||||
"""
|
||||
try:
|
||||
return self.find_visible_element(self._ERROR_MESSAGE).text
|
||||
except:
|
||||
return ""
|
||||
|
||||
def is_login_form_visible(self) -> bool:
|
||||
"""Checks if the login form is visible on the page."""
|
||||
try:
|
||||
self.find_visible_element(self._LOGIN_FORM)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
53
page_objects/profile_editor_page.py
Normal file
53
page_objects/profile_editor_page.py
Normal file
@@ -0,0 +1,53 @@
|
||||
from selenium.webdriver.common import by
|
||||
from selenium.webdriver.common.by import By
|
||||
from page_objects.base_page import BasePage
|
||||
|
||||
class ProfileEditorPage(BasePage):
|
||||
"""
|
||||
Page object for the Profile Editor page.
|
||||
"""
|
||||
|
||||
# Locators
|
||||
USERNAME_INPUT = (By.ID, "name")
|
||||
EMAIL_INPUT = (By.ID, "email")
|
||||
SAVE_BUTTON = (By.XPATH, "//button[text()='Save Changes']")
|
||||
SUCCESS_MESSAGE = (By.XPATH, "//*[contains(text(), 'Profile updated successfully')]") # Assuming a success message appears
|
||||
_PROFILE_TITLE = (By.XPATH,'//*[contains(@id,"content-profile")]//h3')
|
||||
|
||||
def get_page_header(self):
|
||||
"""
|
||||
Gets the header text of the page.
|
||||
Assumes the header is an h1 element.
|
||||
"""
|
||||
return self.get_text((By.TAG_NAME, "h1"))
|
||||
|
||||
def set_username(self, username: str):
|
||||
"""
|
||||
Enters the given username into the username input field.
|
||||
"""
|
||||
self.send_keys(self.USERNAME_INPUT, username)
|
||||
|
||||
def set_email(self, email: str):
|
||||
"""
|
||||
Enters the given email into the email input field.
|
||||
"""
|
||||
self.send_keys(self.EMAIL_INPUT, email)
|
||||
|
||||
def click_save_changes(self):
|
||||
"""
|
||||
Clicks the 'Save Changes' button.
|
||||
"""
|
||||
self.click(self.SAVE_BUTTON)
|
||||
|
||||
def is_success_message_displayed(self) -> bool:
|
||||
"""
|
||||
Checks if the success message is visible.
|
||||
"""
|
||||
try:
|
||||
return self.find_visible_element(self.SUCCESS_MESSAGE).is_displayed()
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
def verify_title_is_profile(self):
|
||||
return self.get_text(self._PROFILE_TITLE)
|
||||
48
page_objects/settings_panel_page.py
Normal file
48
page_objects/settings_panel_page.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from selenium.webdriver.common.by import By
|
||||
from page_objects.base_page import BasePage
|
||||
|
||||
class SettingsPanelPage(BasePage):
|
||||
"""
|
||||
Page object for the Settings Panel page.
|
||||
"""
|
||||
|
||||
|
||||
# Locators
|
||||
_SETTING_TAB_TITLE = (By.XPATH, '//*[contains(@id,"content-settings")]//h3')
|
||||
NOTIFICATIONS_SWITCH = (By.ID, "notifications")
|
||||
THEME_SELECTOR = (By.ID, "theme")
|
||||
|
||||
def get_page_header(self):
|
||||
"""
|
||||
Gets the header text of the page.
|
||||
Assumes the header is an h1 element.
|
||||
"""
|
||||
return self.get_text((By.TAG_NAME, "h1"))
|
||||
|
||||
def verify_title_is_settings(self):
|
||||
return self.get_text(self._SETTING_TAB_TITLE)
|
||||
def toggle_notifications(self):
|
||||
"""
|
||||
Clicks the notifications switch to toggle it.
|
||||
"""
|
||||
self.click(self.NOTIFICATIONS_SWITCH)
|
||||
|
||||
def is_notifications_enabled(self) -> bool:
|
||||
"""
|
||||
Checks if the notifications switch is in the 'on' or 'selected' state.
|
||||
Note: This might need adjustment based on the actual HTML implementation (e.g., aria-checked).
|
||||
"""
|
||||
return self.is_element_selected(self.NOTIFICATIONS_SWITCH)
|
||||
|
||||
def select_theme(self, theme_name: str):
|
||||
"""
|
||||
Selects a theme from the dropdown.
|
||||
|
||||
:param theme_name: The visible text of the theme to select (e.g., "Dark").
|
||||
"""
|
||||
# This is a placeholder. The actual implementation depends on the select/dropdown component.
|
||||
# If it's a standard <select>, this would involve the Select class from Selenium.
|
||||
# from selenium.webdriver.support.ui import Select
|
||||
# select = Select(self.find_element(self.THEME_SELECTOR))
|
||||
# select.select_by_visible_text(theme_name)
|
||||
pass
|
||||
Reference in New Issue
Block a user