import os from playwright.sync_api import Locator, Page, TimeoutError as PlaywrightTimeoutError class BasePage: """Playwright 页面基类:封装通用等待、点击、截图等稳定操作。""" def __init__(self, page: Page): self.page = page def goto(self, url: str, timeout: int = 60000) -> None: self.page.goto(url, wait_until="domcontentloaded", timeout=timeout) self.wait_for_network_idle() def wait_for_network_idle(self, timeout: int = 30000) -> None: try: self.page.wait_for_load_state("networkidle", timeout=timeout) except PlaywrightTimeoutError: self.page.wait_for_load_state("domcontentloaded", timeout=timeout) def wait_for_visible(self, locator: Locator, timeout: int = 10000) -> Locator: locator.wait_for(state="visible", timeout=timeout) return locator def click_if_visible(self, locator: Locator, timeout: int = 3000) -> bool: try: if locator.first.is_visible(timeout=timeout): locator.first.click() self.wait_for_network_idle() return True except Exception: return False return False def safe_click(self, locator: Locator, timeout: int = 10000) -> None: self.wait_for_visible(locator, timeout=timeout) locator.click() self.wait_for_network_idle() def screenshot(self, screenshot_dir: str, file_name: str, full_page: bool = True) -> str: os.makedirs(screenshot_dir, exist_ok=True) screenshot_path = os.path.join(screenshot_dir, file_name) self.page.screenshot(path=screenshot_path, full_page=full_page) return screenshot_path def current_url(self) -> str: return self.page.url def title(self) -> str: return self.page.title() def visible_text_contains(self, keyword: str) -> bool: try: return self.page.get_by_text(keyword, exact=False).first.is_visible(timeout=3000) except Exception: return False