03e152baab
目录结构: tests/web/admin/ 管理端 (Playwright) tests/web/mini_program/ 司机端小程序 (Playwright/微信 WebView) tests/app/driver_android/ 司机安卓 (Appium) tests/app/shipper_android/ 货主安卓 (Appium) tests/app/driver_ios/ 司机苹果 (Appium) tests/app/shipper_ios/ 货主苹果 (Appium) 公共模块: tests/app/_shared.py driver+ensure_logged_in 工厂 tests/app/_base_page.py App Page Object 基类 配置: test_config.yaml 拆分为 6 个独立 section + 货主账号
74 lines
2.8 KiB
Python
74 lines
2.8 KiB
Python
"""通用 App Page Object 基类。"""
|
|
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
from appium.webdriver.common.appiumby import AppiumBy
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
|
|
SCREENSHOTS_DIR = Path("output/screenshots")
|
|
|
|
|
|
class AppBasePage:
|
|
"""App Page Object 基类 — 各端通用。"""
|
|
|
|
def __init__(self, driver, platform: str, timeout_ms: int = 30_000):
|
|
self.driver = driver
|
|
self.platform = platform # "android" | "ios"
|
|
self.timeout = timeout_ms / 1000
|
|
|
|
def wait_visible_by_id(self, accessibility_id: str, timeout_s: float | None = None) -> None:
|
|
wait = WebDriverWait(self.driver, timeout=timeout_s or self.timeout)
|
|
wait.until(
|
|
EC.visibility_of_element_located((AppiumBy.ACCESSIBILITY_ID, accessibility_id))
|
|
)
|
|
|
|
def wait_visible_by_text(self, text: str, timeout_s: float | None = None) -> None:
|
|
wait = WebDriverWait(self.driver, timeout=timeout_s or self.timeout)
|
|
locator = (
|
|
(AppiumBy.XPATH, f"//*[@text='{text}']")
|
|
if self.platform == "android"
|
|
else (AppiumBy.XPATH, f"//*[@label='{text}']")
|
|
)
|
|
wait.until(EC.visibility_of_element_located(locator))
|
|
|
|
def tap_by_id(self, accessibility_id: str) -> None:
|
|
self.wait_visible_by_id(accessibility_id)
|
|
self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, accessibility_id).click()
|
|
|
|
def tap_by_text(self, text: str) -> None:
|
|
strategy = AppiumBy.XPATH
|
|
locator = (
|
|
f"//*[@text='{text}']"
|
|
if self.platform == "android"
|
|
else f"//*[@label='{text}']"
|
|
)
|
|
wait = WebDriverWait(self.driver, timeout=self.timeout)
|
|
wait.until(EC.visibility_of_element_located((strategy, locator)))
|
|
self.driver.find_element(strategy, locator).click()
|
|
|
|
def fill_by_id(self, accessibility_id: str, value: str) -> None:
|
|
self.wait_visible_by_id(accessibility_id)
|
|
element = self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, accessibility_id)
|
|
element.clear()
|
|
element.send_keys(value)
|
|
|
|
def scroll_down(self) -> None:
|
|
size = self.driver.get_window_size()
|
|
self.driver.swipe(
|
|
start_x=size["width"] // 2,
|
|
start_y=int(size["height"] * 0.7),
|
|
end_x=size["width"] // 2,
|
|
end_y=int(size["height"] * 0.3),
|
|
duration=500,
|
|
)
|
|
|
|
def screenshot(self, name: str) -> str:
|
|
scenario_dir = SCREENSHOTS_DIR / self.__class__.__name__
|
|
scenario_dir.mkdir(parents=True, exist_ok=True)
|
|
ts = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
path = str(scenario_dir / f"{name}_{self.platform}_{ts}.png")
|
|
self.driver.save_screenshot(path)
|
|
return path
|