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}")
|