# 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())