refactor(locators): 文本锚点优先的多候选定位 + 失败 DOM 快照
定位健壮性原则: 语义文本 > 组件库稳定 class > 层级结构 > nth-child/绝对路径。
Web (freight_accounting_page):
- 新增 BasePage.first_matching(*候选): 文本锚点优先命中, 旧结构路径兜底
- 13 处定位器改造: 核算/审核通过/确认打款按钮(get_by_role 文本)、
车队长/收款模式表单(.el-form-item label 锚定)、光大单选(label:has-text)、
获取验证码/验证码输入(按钮同行锚定)、message-box 确定等
- 手机号单选保留旧结构路径优先(弹窗含多组电话单选, 文本有歧义)
- 已实况验证: 获取验证码/确认打款/光大锚点唯一命中
App (freight_flow_page):
- 货源 tab: text("货源") 文本锚点优先(登录流程持续验证), 位置序号兜底
- 货源单列表项: RecyclerView(lRrcyclerView) 第一个子项, 全局 instance(3) 兜底
- 选图按钮(ImageView instance(2))保留: 需在途订单才能探测, 当前可用
失败诊断:
- Web 失败时 attach 页面 DOM 快照, App 失败时 attach page_source 到 Allure
验收: 实况锚点解析全部唯一命中; 两条 E2E 通过且 DB 终态均为全流程完成
(status=5, 已结算, 双支付完成)。
This commit is contained in:
@@ -21,6 +21,19 @@ def attach_png(path: str, name: str = "screenshot") -> None:
|
||||
pass # 附件失败不影响用例主流程
|
||||
|
||||
|
||||
def attach_text(content: str, name: str, attachment_type=None) -> None:
|
||||
"""把文本内容(DOM 快照/page_source 等)附加到 Allure 当前用例上。"""
|
||||
if allure is None:
|
||||
return
|
||||
try:
|
||||
allure.attach(
|
||||
content, name=name,
|
||||
attachment_type=attachment_type or allure.attachment_type.TEXT,
|
||||
)
|
||||
except Exception:
|
||||
pass # 附件失败不影响用例主流程
|
||||
|
||||
|
||||
def write_environment_properties(results_dir: str, config: dict) -> None:
|
||||
"""向 allure-results 目录写入 environment.properties(报告环境页展示)。"""
|
||||
if not results_dir:
|
||||
|
||||
@@ -7,7 +7,7 @@ from datetime import datetime
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.core.allure_support import attach_png
|
||||
from tests.core.allure_support import allure, attach_png, attach_text
|
||||
from tests.core.paths import SCREENSHOTS_DIR
|
||||
|
||||
|
||||
@@ -210,7 +210,7 @@ def _perform_ui_login(driver, account: dict, wait) -> None:
|
||||
|
||||
|
||||
def save_failure_screenshot(driver, section_config: dict, platform: str, request) -> str | None:
|
||||
"""用例失败时截图(存盘 + attach Allure),返回路径;未失败返回 None。"""
|
||||
"""用例失败时截图 + 页面源码快照(存盘/attach Allure),返回路径;未失败返回 None。"""
|
||||
if not (
|
||||
section_config.get("screenshot_on_failure", True)
|
||||
and hasattr(request.node, "rep_call")
|
||||
@@ -223,4 +223,10 @@ def save_failure_screenshot(driver, section_config: dict, platform: str, request
|
||||
path = str(scenario_dir / f"FAIL_{platform}_{ts}.png")
|
||||
driver.save_screenshot(path)
|
||||
attach_png(path, name=f"失败截图-{platform}")
|
||||
# page_source 快照: 定位器失效时直接看到当时的控件层级
|
||||
try:
|
||||
attach_text(driver.page_source, name=f"页面源码-{platform}",
|
||||
attachment_type=allure.attachment_type.XML)
|
||||
except Exception:
|
||||
pass
|
||||
return path
|
||||
|
||||
@@ -13,7 +13,7 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.core.allure_support import attach_png
|
||||
from tests.core.allure_support import allure, attach_png, attach_text
|
||||
from tests.core.paths import SCREENSHOTS_DIR
|
||||
|
||||
# 本机 %LOCALAPPDATA%\ms-playwright 下 Chrome for Testing 存在 SxS 激活失败问题,
|
||||
@@ -86,7 +86,7 @@ def pick_available_role(storage_state_dir: Path, browser_name: str) -> str | Non
|
||||
|
||||
|
||||
def save_web_failure_screenshot(page, request, tag: str) -> str | None:
|
||||
"""用例失败时整页截图(存盘 + attach Allure),返回路径;未失败返回 None。
|
||||
"""用例失败时整页截图 + DOM 快照(存盘/attach Allure),返回路径;未失败返回 None。
|
||||
|
||||
Args:
|
||||
page: Playwright Page
|
||||
@@ -102,8 +102,14 @@ def save_web_failure_screenshot(page, request, tag: str) -> str | None:
|
||||
try:
|
||||
page.screenshot(path=path, full_page=True)
|
||||
except Exception:
|
||||
return None
|
||||
pass
|
||||
attach_png(path, name=f"失败截图-{tag}")
|
||||
# DOM 快照: 定位器失效时直接看到当时的页面结构
|
||||
try:
|
||||
attach_text(page.content(), name=f"DOM快照-{tag}",
|
||||
attachment_type=allure.attachment_type.HTML)
|
||||
except Exception:
|
||||
pass
|
||||
return path
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user