This commit is contained in:
HuangHai
2026-01-13 21:37:14 +08:00
parent ddb63403b7
commit 46f17aed11
18 changed files with 712 additions and 98 deletions

View File

@@ -0,0 +1,129 @@
# coding=utf-8
import sys
import os
import time
import asyncio
import uiautomator2 as u2
import cv2
# Add project root to sys.path
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../"))
sys.path.append(project_root)
try:
from Apps.YeLiTe.Kit import detect_cards_cv, draw_rectangles, take_screenshot, get_image_content_md5
from Apps.YeLiTe.Config import Setting
except ImportError as e:
print(f"Import Error: {e}")
sys.exit(1)
async def run_verification():
print(">>> [Step 0] 连接设备...")
try:
d = u2.connect()
info = d.info
print(f"设备已连接: {info.get('productName', 'Unknown Device')}")
except Exception as e:
print(f"设备连接失败: {e}")
return
# 这里我们假设已经在列表页,或者直接启动
# 为了保险,尝试回到桌面重新进? 不,用户说“获取第一屏场站列表”,假设用户已经准备好了环境,或者我们手动进一下
# 为了全自动化,我们调用 Opener 进一下
# 但是 Opener 可能会重启微信,有点慢。
# 我们先判断当前包名,如果是微信,就默认在列表页(或者由用户手动滑到列表页)
# 用户指令暗示是交互式的:"获取第一屏...你去点击一下...停止程序"
# 所以我们假设当前就在列表页
current_app = d.app_current()
print(f"当前前台应用: {current_app.get('package')}")
if "com.tencent.mm" not in current_app.get('package', ''):
print("警告:微信似乎不在前台,请确保手机显示的是【驿来特】小程序列表页")
print("给你 5 秒钟调整手机屏幕...")
time.sleep(5)
else:
print("检测到微信在前台,准备截图...")
time.sleep(2) # 稍微等一下稳定
# 1. 获取第一屏场站列表,然后截图
timestamp = int(time.time())
list_screenshot_path = os.path.join(project_root, "Output", f"verify_step1_list_{timestamp}.jpg")
print(f"\n>>> [Step 1] 截图列表页: {list_screenshot_path}")
d.screenshot(list_screenshot_path)
# 2. 绿框标注,标识模拟点击点
print("\n>>> [Step 2] 识别卡片并标注...")
# 使用配置中的排除比例
cards = detect_cards_cv(list_screenshot_path, top_ratio=Setting.SAFE_EXCLUDE_RATIO, bottom_ratio=Setting.BOTTOM_SAFE_EXCLUDE_RATIO)
if not cards:
print("!!! [Error] 未检测到任何场站卡片,测试终止")
print(f"请检查截图: {list_screenshot_path}")
return
print(f"检测到 {len(cards)} 个卡片区域")
# 在图上绘制绿框和红点
debug_img = cv2.imread(list_screenshot_path)
if debug_img is None:
print("读取截图失败")
return
first_card = cards[0]
# 计算点击点:中心点
click_x = int((first_card[0] + first_card[2]) / 2)
click_y = int((first_card[1] + first_card[3]) / 2)
# 绘制所有卡片
for i, box in enumerate(cards):
# 绿框
cv2.rectangle(debug_img, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (0, 255, 0), 2)
# 标号
cv2.putText(debug_img, str(i+1), (int(box[0]), int(box[1])+30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
# 绘制第一个卡片的点击点 (实心红圆)
cv2.circle(debug_img, (click_x, click_y), 15, (0, 0, 255), -1)
# 绘制同心圆
cv2.circle(debug_img, (click_x, click_y), 25, (0, 0, 255), 2)
marked_path = os.path.join(project_root, "Output", f"verify_step2_marked_{timestamp}.jpg")
cv2.imwrite(marked_path, debug_img)
print(f">>> 已生成标注图 (绿框+红点): {marked_path}")
print(f">>> 模拟点击目标: 第 1 个卡片, 坐标 ({click_x}, {click_y})")
# 计算点击前的 MD5
before_md5 = get_image_content_md5(list_screenshot_path, top_ratio=Setting.SAFE_EXCLUDE_RATIO, bottom_ratio=Setting.BOTTOM_SAFE_EXCLUDE_RATIO)
# 3. 你去点击一下,等一会
print(f"\n>>> [Step 3] 执行点击操作...")
# 使用 shell input tap
cmd = f"input tap {click_x} {click_y}"
print(f"执行命令: {cmd}")
d.shell(cmd)
print(">>> 点击完成,等待 5 秒让页面跳转...")
await asyncio.sleep(5)
# 4. 再继续截图,判断是否进入
after_screenshot_path = os.path.join(project_root, "Output", f"verify_step4_after_{timestamp}.jpg")
print(f"\n>>> [Step 4] 截图当前页面: {after_screenshot_path}")
d.screenshot(after_screenshot_path)
after_md5 = get_image_content_md5(after_screenshot_path, top_ratio=Setting.SAFE_EXCLUDE_RATIO, bottom_ratio=Setting.BOTTOM_SAFE_EXCLUDE_RATIO)
print("\n>>> [Step 5] 结果验证")
print("-" * 30)
print(f"点击前 MD5: {before_md5}")
print(f"点击后 MD5: {after_md5}")
if before_md5 != after_md5:
print(">>> [SUCCESS] 判定结果: 成功进入详情页! (MD5发生变化)")
else:
print(">>> [FAILURE] 判定结果: 未进入详情页 (MD5未变化)")
print("可能原因: 1. 点击无效 2. 页面加载极慢 3. 已经是详情页(误判)")
print("-" * 30)
if __name__ == "__main__":
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(run_verification())