115 lines
4.7 KiB
Python
115 lines
4.7 KiB
Python
# coding=utf-8
|
||
import asyncio
|
||
import os
|
||
import sys
|
||
import time
|
||
import uiautomator2 as u2
|
||
import cv2
|
||
|
||
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||
if project_root not in sys.path:
|
||
sys.path.append(project_root)
|
||
|
||
from Apps.TeLaiDian.Kit import setup_logger, take_screenshot, read_image, save_image
|
||
from Apps.TeLaiDian.Config.Setting import SAFE_EXCLUDE_RATIO, BOTTOM_SAFE_EXCLUDE_RATIO
|
||
|
||
|
||
logger = setup_logger("TeLaiDianScrollTest", clear_old_log=False)
|
||
|
||
# 根据最新红点截图重新估算的顶部“价格”标签归一化坐标(0-1000)
|
||
# 这里调成:X ≈ 22% 屏宽,Y ≈ 13% 屏高
|
||
PRICE_TAB_X_NORM = 220
|
||
PRICE_TAB_Y_NORM = 130
|
||
|
||
# 价格信息卡片中左侧“当前价”红色数字的大致归一化坐标(0-1000)
|
||
# 估算:X ≈ 23% 屏宽,Y ≈ 38% 屏高
|
||
PRICE_ENTRY_X_NORM = 230
|
||
PRICE_ENTRY_Y_NORM = 380
|
||
|
||
|
||
async def run_scroll_test():
|
||
d = u2.connect()
|
||
w, h = d.window_size()
|
||
|
||
logger.info("=== 特来电详情页第2页滚动安全性测试开始 ===")
|
||
logger.info("请先手动进入某个场站详情页的第2页状态,然后执行本脚本。脚本会尽可能多次大幅向上滑动,直到页面不再变化。")
|
||
|
||
first_screen = take_screenshot(d, f"tld_scrolltest_start_{int(time.time())}.jpg")
|
||
logger.info(f"[测试] 起始界面截图: {first_screen}")
|
||
|
||
last_md5 = None
|
||
stable_count = 0
|
||
max_round = 30
|
||
|
||
from Apps.TeLaiDian.Kit import get_image_content_md5
|
||
|
||
for idx in range(max_round):
|
||
# 1. 先执行一次“大力向上滑动”
|
||
start_x = int(w * 0.9)
|
||
start_y = int(h * 0.85)
|
||
end_y = int(h * 0.25)
|
||
logger.info(f"[测试] 第 {idx + 1} 轮大幅向上滑动: ({start_x}, {start_y}) -> ({start_x}, {end_y})")
|
||
d.swipe(start_x, start_y, start_x, end_y, 0.25)
|
||
await asyncio.sleep(1.0)
|
||
|
||
# 2. 滑动完成后再截图、比较内容是否还在变化
|
||
screen_path = take_screenshot(d, f"tld_scrolltest_{int(time.time())}_{idx}.jpg")
|
||
logger.info(f"[测试] 第 {idx + 1} 轮滑动后的截图: {screen_path}")
|
||
curr_md5 = get_image_content_md5(
|
||
screen_path,
|
||
top_ratio=SAFE_EXCLUDE_RATIO,
|
||
bottom_ratio=BOTTOM_SAFE_EXCLUDE_RATIO,
|
||
)
|
||
if last_md5 is not None and curr_md5 == last_md5:
|
||
stable_count += 1
|
||
logger.info(f"[测试] 页面内容连续第 {stable_count} 次无变化")
|
||
else:
|
||
stable_count = 0
|
||
last_md5 = curr_md5
|
||
|
||
if stable_count >= 2:
|
||
logger.info("[测试] 检测到页面多次无变化,认为已到达顶部固定区域,提前结束测试。")
|
||
break
|
||
|
||
final_screen = take_screenshot(d, f"tld_scrolltest_end_{int(time.time())}.jpg")
|
||
logger.info(f"[测试] 结束时界面截图: {final_screen}")
|
||
|
||
# 使用写死的归一化坐标点击顶部“价格”标签
|
||
tab_x = int(PRICE_TAB_X_NORM * w / 1000)
|
||
tab_y = int(PRICE_TAB_Y_NORM * h / 1000)
|
||
logger.info(f"[测试] 使用固定归一化坐标点击顶部“价格”标签: 归一化({PRICE_TAB_X_NORM}, {PRICE_TAB_Y_NORM}) -> 像素({tab_x}, {tab_y})")
|
||
try:
|
||
d.click(tab_x, tab_y)
|
||
await asyncio.sleep(1.0)
|
||
after_tab_screen = take_screenshot(d, f"tld_scrolltest_after_price_tab_{int(time.time())}.jpg")
|
||
logger.info(f"[测试] 点击顶部“价格”标签后的界面截图: {after_tab_screen}")
|
||
try:
|
||
img = read_image(after_tab_screen)
|
||
if img is not None:
|
||
cv2.circle(img, (tab_x, tab_y), 20, (0, 0, 255), -1)
|
||
|
||
entry_x = int(PRICE_ENTRY_X_NORM * w / 1000)
|
||
entry_y = int(PRICE_ENTRY_Y_NORM * h / 1000)
|
||
cv2.circle(img, (entry_x, entry_y), 20, (0, 0, 255), -1)
|
||
|
||
debug_path = after_tab_screen.replace(".jpg", f"_click_{tab_x}_{tab_y}_price_{entry_x}_{entry_y}.jpg")
|
||
save_image(debug_path, img)
|
||
logger.info(f"[测试] 已在截图上标记价格标签和下方每度价格的红点: {debug_path}")
|
||
else:
|
||
logger.warning(f"[测试] 加载点击后截图失败,无法绘制红点: {after_tab_screen}")
|
||
except Exception as e:
|
||
logger.error(f"[测试] 绘制价格标签或下方价格红点失败: {e}")
|
||
except Exception as e:
|
||
logger.error(f"[测试] 点击顶部“价格”标签失败: {e}")
|
||
|
||
logger.info("=== 特来电详情页第2页滚动安全性测试结束 ===")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
try:
|
||
asyncio.run(run_scroll_test())
|
||
except KeyboardInterrupt:
|
||
logger.info("用户中断了滚动测试。")
|
||
except Exception as e:
|
||
logger.exception(f"滚动测试运行异常: {e}")
|