Files
cjgc_data/actions.py
2026-03-14 17:53:14 +08:00

321 lines
15 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 = driver_utils.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')
def __init__(self, driver=None, wait=None, device_id=None):
self.driver = driver
self.wait = wait
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()
# @staticmethod
# def get_device_id() -> str:
# """
# 获取设备ID优先使用已连接设备否则使用全局配置
# """
# try:
# # 检查已连接设备
# result = subprocess.run(
# ["adb", "devices"],
# capture_output=True,
# text=True,
# timeout=10
# )
# 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:
try:
if not driver_utils.check_session_valid(self.driver, self.device_id):
logging.warning(f"设备 {self.device_id} 会话无效,尝试重新连接驱动...")
self.driver, self.wait = driver_utils.reconnect_driver(self.device_id, self.driver)
if not self.driver:
logging.error(f"设备 {self.device_id} 驱动重连失败")
return False
except Exception as inner_e:
logging.warning(f"设备 {self.device_id} 检查会话状态时出错: {str(inner_e)}")
return False
# # 使用全局函数初始化驱动
# 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)