188 lines
6.4 KiB
Python
188 lines
6.4 KiB
Python
from selenium.webdriver.remote.webdriver import WebDriver
|
|
from selenium.webdriver.remote.webelement import WebElement
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
import time
|
|
|
|
class BasePage:
|
|
"""
|
|
The BasePage class serves as a foundation for all page objects.
|
|
It encapsulates common Selenium operations to promote code reuse and
|
|
improve test maintenance.
|
|
"""
|
|
|
|
def __init__(self, driver: WebDriver):
|
|
"""
|
|
Initializes the BasePage with a WebDriver instance.
|
|
|
|
:param driver: The WebDriver instance to interact with the browser.
|
|
"""
|
|
self.driver = driver
|
|
self.wait = WebDriverWait(driver, 10) # Default explicit wait of 10 seconds
|
|
|
|
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 = base_url.rstrip('/') + path
|
|
self.driver.get(url)
|
|
|
|
def find_element(self, locator: tuple) -> WebElement:
|
|
"""
|
|
Finds and returns a web element using an explicit wait.
|
|
|
|
:param locator: A tuple containing the locator strategy and value
|
|
(e.g., (By.ID, "my-element")).
|
|
:return: The located WebElement.
|
|
"""
|
|
return self.wait.until(EC.presence_of_element_located(locator))
|
|
|
|
def find_visible_element(self, locator: tuple) -> WebElement:
|
|
"""
|
|
Finds and returns a web element that is visible on the page.
|
|
|
|
:param locator: A tuple containing the locator strategy and value.
|
|
:return: The located and visible WebElement.
|
|
"""
|
|
return self.wait.until(EC.visibility_of_element_located(locator))
|
|
|
|
def click(self, locator: tuple):
|
|
"""
|
|
Waits for an element to be clickable and then clicks on it.
|
|
|
|
:param locator: A tuple containing the locator strategy and value.
|
|
"""
|
|
element = self.wait.until(EC.element_to_be_clickable(locator))
|
|
element.click()
|
|
|
|
def send_keys(self, locator: tuple, text: str):
|
|
"""
|
|
Finds an element, clears its content, and sends keys to it.
|
|
|
|
:param locator: A tuple containing the locator strategy and value.
|
|
:param text: The text to send to the element.
|
|
"""
|
|
element = self.find_element(locator)
|
|
element.clear()
|
|
element.send_keys(text)
|
|
|
|
def get_text(self, locator: tuple) -> str:
|
|
"""
|
|
Finds an element and returns its text content.
|
|
|
|
:param locator: A tuple containing the locator strategy and value.
|
|
:return: The text content of the element.
|
|
"""
|
|
element = self.find_element(locator)
|
|
return element.text
|
|
|
|
def is_element_selected(self, locator: tuple) -> bool:
|
|
"""
|
|
Checks if a checkbox or radio button element is selected.
|
|
|
|
:param locator: A tuple containing the locator strategy and value.
|
|
:return: True if the element is selected, False otherwise.
|
|
"""
|
|
element = self.find_element(locator)
|
|
return element.is_selected()
|
|
|
|
def is_element_enabled(self, locator: tuple) -> bool:
|
|
"""
|
|
Checks if a form element is enabled.
|
|
|
|
:param locator: A tuple containing the locator strategy and value.
|
|
:return: True if the element is enabled, False otherwise.
|
|
"""
|
|
element = self.find_element(locator)
|
|
return element.is_enabled()
|
|
|
|
def switch_to_alert(self):
|
|
"""
|
|
Switches the driver's focus to a browser alert.
|
|
|
|
:return: The alert object.
|
|
"""
|
|
return self.wait.until(EC.alert_is_present())
|
|
|
|
|
|
def back(self):
|
|
"""
|
|
Navigates one step backward in the browser history.
|
|
"""
|
|
self.driver.back()
|
|
|
|
def forward(self):
|
|
"""
|
|
Navigates one step forward in the browser history.
|
|
"""
|
|
self.driver.forward()
|
|
|
|
def refresh(self):
|
|
"""
|
|
Refreshes the current page.
|
|
"""
|
|
self.driver.refresh()
|
|
|
|
def take_screenshot(self, name: str = "screenshot"):
|
|
"""
|
|
Captures a screenshot of the current browser window.
|
|
|
|
:param name: Base name for the screenshot file.
|
|
:return: The filename of the saved screenshot.
|
|
"""
|
|
timestamp = time.strftime("%Y%m%d_%H%M%S")
|
|
filename = f"{name}_{timestamp}.png"
|
|
self.driver.save_screenshot(filename)
|
|
return filename
|
|
|
|
def find_elements(self, locator: tuple):
|
|
"""
|
|
Finds and returns a list of web elements using an explicit wait.
|
|
|
|
:param locator: A tuple containing the locator strategy and value
|
|
(e.g., (By.CLASS_NAME, "items")).
|
|
:return: A list of located WebElements.
|
|
"""
|
|
return self.wait.until(EC.presence_of_all_elements_located(locator))
|
|
|
|
def scroll_into_view(self, locator: tuple):
|
|
"""
|
|
Scrolls the page until the specified element is in view.
|
|
|
|
:param locator: A tuple containing the locator strategy and value.
|
|
"""
|
|
element = self.find_element(locator)
|
|
self.driver.execute_script("arguments[0].scrollIntoView(true);", element)
|
|
|
|
def click_by_js(self, locator: tuple):
|
|
"""
|
|
Clicks on an element using JavaScript execution.
|
|
Useful when standard Selenium click does not work.
|
|
|
|
:param locator: A tuple containing the locator strategy and value.
|
|
"""
|
|
element = self.find_element(locator)
|
|
self.driver.execute_script("arguments[0].click();", element)
|
|
|
|
def wait_for_text(self, locator: tuple, text: str):
|
|
"""
|
|
Waits until the specified text is present within an element.
|
|
|
|
:param locator: A tuple containing the locator strategy and value.
|
|
:param text: The text to wait for in the element.
|
|
: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))
|