first commit

This commit is contained in:
2026-03-12 17:03:56 +08:00
commit aa4d4c7d7c
48 changed files with 10958 additions and 0 deletions

302
actions.py Normal file
View File

@@ -0,0 +1,302 @@
import logging
import os
import time
import subprocess
from tkinter import E
from appium import webdriver
from appium.options.android import UiAutomator2Options
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from page_objects.download_tabbar_page import DownloadTabbarPage
from page_objects.measure_tabbar_page import MeasureTabbarPage
from page_objects.section_mileage_config_page import SectionMileageConfigPage
from page_objects.upload_config_page import UploadConfigPage
from page_objects.more_download_page import MoreDownloadPage
from page_objects.screenshot_page import ScreenshotPage
import globals.driver_utils as driver_utils # 导入驱动工具模块
import globals.global_variable as global_variable
from page_objects.login_page import LoginPage
import globals.apis as apis
import globals.create_link as create_link
class DeviceAutomation:
def __init__(self, device_id=None):
# 如果没有提供设备ID则自动获取
if device_id is None:
self.device_id = self.get_device_id()
else:
self.device_id = device_id
# 初始化权限
if driver_utils.grant_appium_permissions(self.device_id):
logging.info(f"设备 {self.device_id} 授予Appium权限成功")
else:
logging.warning(f"设备 {self.device_id} 授予Appium权限失败")
# 确保Appium服务器正在运行,不在运行则启动
if not driver_utils.check_server_status(4723):
driver_utils.start_appium_server()
# 初始化Appium驱动和页面对象
self.init_driver()
# 创建测试结果目录
self.results_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_results')
@staticmethod
def get_device_id() -> str:
"""
获取设备ID优先使用已连接设备否则使用全局配置
"""
try:
# 检查已连接设备
result = subprocess.run(
["adb", "devices"],
capture_output=True,
text=True,
timeout=10
)
# # 解析设备列表
# for line in result.stdout.strip().split('\n')[1:]:
# if line.strip() and "device" in line and "offline" not in line:
# device_id = line.split('\t')[0]
# logging.info(f"使用已连接设备: {device_id}")
# global_variable.GLOBAL_DEVICE_ID = device_id
# return device_id
target_port = "4723"
for line in result.stdout.strip().split('\n')[1:]:
if line.strip() and "device" in line and "offline" not in line:
device_id = line.split('\t')[0]
# 检查是否为无线设备且端口为4723
if ':' in device_id:
ip_port = device_id.split(':')
if len(ip_port) == 2 and ip_port[1] == target_port:
logging.info(f"找到目标无线设备(端口{target_port}): {device_id}")
global_variable.GLOBAL_DEVICE_ID = device_id
return device_id
# 如果没有找到端口4723的设备找其他无线设备
for line in result.stdout.strip().split('\n')[1:]:
if line.strip() and "device" in line and "offline" not in line:
device_id = line.split('\t')[0]
# 检查是否为无线设备(任何端口)
if ':' in device_id and device_id.split(':')[-1].isdigit():
logging.info(f"未找到端口{target_port}的设备,使用其他无线设备: {device_id}")
global_variable.GLOBAL_DEVICE_ID = device_id
return device_id
# 如果没有任何无线设备,找有线设备
for line in result.stdout.strip().split('\n')[1:]:
if line.strip() and "device" in line and "offline" not in line:
device_id = line.split('\t')[0]
logging.info(f"未找到无线设备,使用有线设备: {device_id}")
global_variable.GLOBAL_DEVICE_ID = device_id
return device_id
logging.error("未找到任何可用设备")
return None
except Exception as e:
logging.warning(f"设备检测失败: {e}")
# 使用全局配置
device_id = global_variable.GLOBAL_DEVICE_ID
logging.info(f"使用全局配置设备: {device_id}")
return device_id
def init_driver(self):
"""初始化Appium驱动"""
try:
# 使用全局函数初始化驱动
self.driver, self.wait = driver_utils.init_appium_driver(self.device_id)
# 初始化页面对象
logging.info(f"设备 {self.device_id} 开始初始化页面对象")
self.login_page = LoginPage(self.driver, self.wait)
self.download_tabbar_page = DownloadTabbarPage(self.driver, self.wait, self.device_id)
self.measure_tabbar_page = MeasureTabbarPage(self.driver, self.wait,self.device_id)
self.section_mileage_config_page = SectionMileageConfigPage(self.driver, self.wait, self.device_id)
self.upload_config_page = UploadConfigPage(self.driver, self.wait, self.device_id)
self.more_download_page = MoreDownloadPage(self.driver, self.wait,self.device_id)
self.screenshot_page = ScreenshotPage(self.driver, self.wait, self.device_id)
logging.info(f"设备 {self.device_id} 所有页面对象初始化完成")
# 检查应用是否成功启动
if driver_utils.is_app_launched(self.driver):
logging.info(f"设备 {self.device_id} 沉降观测App已成功启动")
else:
logging.warning(f"设备 {self.device_id} 应用可能未正确启动init_driver")
driver_utils.launch_app_manually(self.driver)
except Exception as e:
logging.error(f"设备 {self.device_id} 初始化驱动失败: {str(e)}")
raise
def run_automation(self):
"""根据当前应用状态处理相应的操作"""
try:
max_retry = 3 # 限制最大重试次数
retry_count = 0
while retry_count < max_retry:
login_btn_exists = self.login_page.is_login_page()
if not login_btn_exists:
logging.error(f"设备 {self.device_id} 未知应用状态,无法确定当前页面,跳转到登录页面")
if self.login_page.navigate_to_login_page(self.driver, self.device_id):
logging.info(f"设备 {self.device_id} 成功跳转到登录页面")
else:
logging.error(f"设备 {self.device_id} 跳转到登录页面失败")
retry_count += 1
continue
# 处理登录页面状态
logging.info(f"设备 {self.device_id} 检测到登录页面,执行登录操作")
max_retries_login = 3
login_success = False
for attempt in range(max_retries_login + 1):
if self.login_page.login("wangshun"):
login_success = True
break
else:
if attempt < max_retries_login:
logging.warning(f"设备 {self.device_id} 登录失败,准备重试 ({attempt + 1}/{max_retries_login})")
time.sleep(2) # 等待2秒后重试
else:
logging.error(f"设备 {self.device_id} 登录失败,已达到最大重试次数")
if login_success:
break
elif retry_count == max_retry-1:
logging.error(f"设备 {self.device_id} 处理登录页面失败,已达到最大重试次数")
return False
else:
retry_count += 1
# login_btn_exists = self.login_page.is_login_page()
# if not login_btn_exists:
# logging.error(f"设备 {self.device_id} 未知应用状态,无法确定当前页面,跳转到登录页面")
# if self.login_page.navigate_to_login_page(self.driver, self.device_id):
# logging.info(f"设备 {self.device_id} 成功跳转到登录页面")
# return self.run_automation() # 递归调用处理登录后的状态
# else:
# logging.error(f"设备 {self.device_id} 跳转到登录页面失败")
# return False
# # 处理登录页面状态
# logging.info(f"设备 {self.device_id} 检测到登录页面,执行登录操作")
# max_retries = 1
# login_success = False
# for attempt in range(max_retries + 1):
# if self.login_page.login():
# login_success = True
# break
# else:
# if attempt < max_retries:
# logging.warning(f"设备 {self.device_id} 登录失败,准备重试 ({attempt + 1}/{max_retries})")
# time.sleep(2) # 等待2秒后重试
# else:
# logging.error(f"设备 {self.device_id} 登录失败,已达到最大重试次数")
# if not login_success:
# return False
logging.info(f"设备 {self.device_id} 登录成功,继续执行更新操作")
time.sleep(1)
# 执行更新操作
if not self.download_tabbar_page.download_tabbar_page_manager():
logging.error(f"设备 {self.device_id} 更新操作执行失败")
return False
task_count = 0
max_tasks = 1 # 最大任务数量,防止无限循环
while task_count < max_tasks:
# 获取测量任务
logging.info(f"设备 {self.device_id} 获取测量任务 (第{task_count + 1}次)")
# task_data = apis.get_measurement_task()
# logging.info(f"设备 {self.device_id} 获取到的测量任务: {task_data}")
task_data = {
"id": 39,
"user_name": "czsczq115ykl",
"name": "czsczq115ykl",
"line_num": "L179451",
"line_name": "CDWZQ-2标-资阳沱江特大桥-23-35-山区",
"remaining": "0",
"status": 1
}
if not task_data:
logging.info(f"设备 {self.device_id} 未获取到状态为1的测量任务等待后重试")
time.sleep(1) # 等待1秒后重试
break
# continue
# 设置全局变量
global_variable.GLOBAL_CURRENT_PROJECT_NAME = task_data.get('line_name', '')
global_variable.GLOBAL_LINE_NUM = task_data.get('line_num', '')
logging.info(f"设备 {self.device_id} 当前要处理的项目名称:{global_variable.GLOBAL_CURRENT_PROJECT_NAME}")
# 执行测量操作
# logging.info(f"设备 {self.device_id} 开始执行测量操作")
if not self.measure_tabbar_page.measure_tabbar_page_manager():
logging.error(f"设备 {self.device_id} 测量操作执行失败")
# # 返回到测量页面
# self.driver.back()
# self.check_and_click_confirm_popup_appium()
continue # 继续下一个任务
logging.info(f"设备 {self.device_id} 测量页面操作执行成功")
# 在测量操作完成后执行断面里程配置
logging.info(f"设备 {self.device_id} 开始执行断面里程配置")
if not self.section_mileage_config_page.section_mileage_config_page_manager():
logging.error(f"设备 {self.device_id} 断面里程配置执行失败")
continue # 继续下一个任务
# 任务完成后短暂等待
logging.info(f"设备 {self.device_id}{task_count}个任务完成")
task_count += 1
logging.info(f"设备 {self.device_id} 已完成{task_count}个任务,结束打数据流程")
if task_count == 0:
logging.error(f"没有完成打数据的线路,结束任务")
return False
# GLOBAL_TESTED_BREAKPOINT_LIST 把已打完的写入日志文件
with open(os.path.join(self.results_dir, "打数据完成线路.txt"), "w", encoding='utf-8') as f:
for bp in global_variable.GLOBAL_TESTED_BREAKPOINT_LIST:
f.write(f"{bp}\n")
return task_count > 0
except Exception as e:
logging.error(f"设备 {self.device_id} 处理应用状态时出错: {str(e)}")
return False
# 主执行逻辑
if __name__ == "__main__":
create_link.setup_adb_wireless()
automation = None
try:
automation = DeviceAutomation()
success = automation.run_automation()
if success:
logging.info(f"设备 {automation.device_id} 自动化流程执行成功")
else:
logging.error(f"设备 {automation.device_id} 自动化流程执行失败")
except Exception as e:
logging.error(f"设备执行出错: {str(e)}")
finally:
if automation:
driver_utils.safe_quit_driver(automation.driver, automation.device_id)