feat(base_page): 新增BasePage基础操作
- 优化 is_visible,支持快速状态检查。 - 新增 log_screenshot/log_screenshot_bytes 截图。 - 更新 README.md。 - 其他优化。
This commit is contained in:
@@ -11,12 +11,14 @@
|
||||
"""
|
||||
import logging
|
||||
import secrets
|
||||
from typing import Type, TypeVar, List, Tuple
|
||||
|
||||
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')
|
||||
@@ -29,7 +31,74 @@ class BasePage(CoreDriver):
|
||||
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):
|
||||
|
||||
@@ -58,7 +58,7 @@ class CoreDriver:
|
||||
"""
|
||||
return f"http://{self._host}:{self._port}"
|
||||
|
||||
def server_config(self, host: str = APPIUM_HOST, port: int = APPIUM_PORT)-> 'CoreDriver':
|
||||
def server_config(self, host: str = APPIUM_HOST, port: int = APPIUM_PORT) -> 'CoreDriver':
|
||||
"""
|
||||
配置服务器信息。支持链式调用。
|
||||
:param host: ip
|
||||
@@ -358,7 +358,7 @@ class CoreDriver:
|
||||
method = EC.visibility_of_element_located(mark)
|
||||
|
||||
text = self.explicit_wait(method, timeout).text
|
||||
logger.info(f"获取到的文本{text}")
|
||||
logger.info(f"获取到的文本: {text}")
|
||||
return text
|
||||
|
||||
def get_attribute(self, by: str, value: str, name: str, timeout: Optional[float] = None) -> str:
|
||||
@@ -597,22 +597,6 @@ class CoreDriver:
|
||||
"""判断当前驱动会话是否仍然存活。"""
|
||||
return self.driver is not None and self.driver.session_id is not None
|
||||
|
||||
# --- 断言逻辑 ---
|
||||
def assert_text(self, by: str, value: str, expected_text: str, timeout: Optional[float] = None) -> 'CoreDriver':
|
||||
"""
|
||||
断言元素的文本内容是否符合预期。
|
||||
:param by: 定位策略。
|
||||
:param value: 定位值。
|
||||
:param expected_text: 期望的文本。
|
||||
:param timeout: 等待元素可见的超时时间。
|
||||
:return: self,支持链式调用。
|
||||
:raises AssertionError: 如果文本不匹配。
|
||||
"""
|
||||
actual = self.get_text(by, value, timeout)
|
||||
assert actual == expected_text, f"断言失败: 期望 {expected_text}, 实际 {actual}"
|
||||
logger.info(f"断言通过: 文本匹配 '{actual}'")
|
||||
return self
|
||||
|
||||
def quit(self):
|
||||
"""安全关闭 Appium 驱动并断开连接。"""
|
||||
if self.driver:
|
||||
|
||||
Reference in New Issue
Block a user