Files
AppAutoTest/core/base_page.py
CNWei fd6f4fbcbe feat(base_page): 新增BasePage基础操作
- 优化 is_visible,支持快速状态检查。
- 新增 log_screenshot/log_screenshot_bytes 截图。
- 更新 README.md。
- 其他优化。
2026-01-30 18:06:15 +08:00

132 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# coding=utf-8
"""
@author: CNWei,ChenWei
@Software: PyCharm
@contact: t6g888@163.com
@file: base_page
@date: 2026/1/26 17:33
@desc:
"""
import logging
import secrets
from typing import Type, TypeVar, List, Tuple, Optional
import allure
from pathlib import Path
from appium import webdriver
from selenium.common import TimeoutException
from core.driver import CoreDriver
from utils.decorators import exception_capture
# 定义一个泛型用于类型推断IDE 依然会有补全提示)
T = TypeVar('T', bound='BasePage')
logger = logging.getLogger(__name__)
class BasePage(CoreDriver):
def __init__(self, driver: webdriver.Remote):
super().__init__(driver)
# 定义常见弹窗的关闭按钮定位
def log_screenshot(self, label: str = "步骤截图"):
"""
业务级截图:执行截图并附加到 Allure 报告。
用户可自由手动调用此方法。
"""
path_str = self.full_screen_screenshot(name=label)
if path_str:
img_path = Path(path_str)
if img_path.exists():
allure.attach.file(
img_path,
name=label,
attachment_type=allure.attachment_type.PNG
)
def log_screenshot_bytes(self, label: str = "步骤截图"):
"""
业务级截图:执行截图并附加到 Allure 报告。
用户可自由手动调用此方法。
"""
_img: bytes = self.driver.get_screenshot_as_png()
allure.attach(
_img,
name=label,
attachment_type=allure.attachment_type.PNG
)
# --- 常用断言逻辑 ---
def assert_text(self, by: str, value: str, expected_text: str, timeout: Optional[float] = None) -> 'BasePage':
"""
断言元素的文本内容是否符合预期。
:param by: 定位策略。
:param value: 定位值。
:param expected_text: 期望的文本。
:param timeout: 等待元素可见的超时时间。
:return: self支持链式调用。
:raises AssertionError: 如果文本不匹配。
"""
# 1. 增强报告展示:将断言动作包装为一个清晰的步骤
step_name = f"断言校验 | 预期结果: '{expected_text}'"
with allure.step(step_name):
actual = self.get_text(by, value, timeout)
# 2. 动态附件:在报告中直观对比,方便后期排查
allure.attach(
f"预期值: {expected_text}\n实际值: {actual}",
name="文本对比结果",
attachment_type=allure.attachment_type.TEXT
)
# 3. 执行核心断言
# 如果断言失败,抛出的 AssertionError 会被 conftest.py 中的 Hook 捕获并截图
assert actual == expected_text, f"断言失败: 期望 {expected_text}, 实际 {actual}"
logger.info(f"断言通过: 文本匹配 '{actual}'")
return self
# 这里放全局通用的 Page 属性和逻辑
def assert_visible(self, by: str, value: str, msg: str = "元素可见性校验"):
"""
增强版断言:成功/失败均截图
"""
with allure.step(f"断言检查: {msg}"):
try:
element = self.find_element(by, value)
assert element.is_displayed()
# 成功存证
except Exception as e:
raise e
# 封装一些所有页面通用的元动作
def clear_permission_popups(self):
# 普适性黑名单
_black_list = [
("id", "com.android.packageinstaller:id/permission_allow_button"),
("xpath", "//*[@text='始终允许']"),
("xpath", "//*[@text='稍后提醒']"),
("xpath", "//*[@text='以后再说']"),
("id", "com.app:id/iv_close_global_ad"),
("accessibility id", "Close"), # iOS 常用
]
self.clear_popups(_black_list)
def clear_business_ads(self):
"""在这里定义一些全 App 通用的业务广告清理"""
_ads = [("id", "com.app:id/global_ad_close")]
return self.clear_popups(_ads)
def get_toast(self, text):
return self.is_visible("text", text)
def go_to(self, page_name: Type[T]) -> T:
"""
通用的页面跳转/获取方法
:param page_name: 目标页面类
:return: 目标页面的实例
"""
logger.info(f"跳转到页面: {page_name.__name__}")
return page_name(self.driver)