串起截图和上传

This commit is contained in:
2026-02-10 09:20:12 +08:00
parent ac4d41c70b
commit 2441031bb6
26 changed files with 18384 additions and 18432 deletions

View File

@@ -19,7 +19,8 @@ import globals.global_variable as global_variable # 导入全局变量模块
class ScreenshotPage:
def __init__(self, driver, wait, device_id=None):
self.driver = driver
self.wait = wait
# self.wait = wait
self.wait = WebDriverWait(self.driver, 0.5)
self.device_id = device_id
self.logger = logging.getLogger(__name__)
self.all_items = set()
@@ -233,7 +234,7 @@ class ScreenshotPage:
def check_apply_btn(self):
"""检查是否有平差处理按钮"""
try:
apply_btn = WebDriverWait(self.driver, 5).until(
apply_btn = WebDriverWait(self.driver, 1).until(
EC.element_to_be_clickable((AppiumBy.ID, "com.bjjw.cjgc:id/point_measure_btn"))
)
if apply_btn.is_displayed():
@@ -548,117 +549,6 @@ class ScreenshotPage:
self.logger.error(f"截图时发生错误: {str(e)}")
return False
def wait_for_measurement_end(self, timeout=900):
"""
等待按钮变成"测量结束"最多15分钟包含驱动重新初始化机制
Args:
timeout: 超时时间默认900秒15分钟
Returns:
bool: 是否成功等到测量结束按钮
"""
try:
# 更新WebDriverWait等待时间为900秒
self.wait = WebDriverWait(self.driver, 900)
self.logger.info(f"设备等待测量结束按钮出现,最多等待 {timeout}")
start_time = time.time()
reinit_attempts = 0
max_reinit_attempts = 3 # 最大重新初始化次数
while time.time() - start_time < timeout:
try:
# 使用XPath查找文本为"测量结束"的按钮
measurement_end_button = self.driver.find_element(
AppiumBy.XPATH,
"//android.widget.Button[@text='测量结束']"
)
if measurement_end_button.is_displayed() and measurement_end_button.is_enabled():
self.logger.info(f"设备检测到测量结束按钮")
return True
except NoSuchElementException:
# 按钮未找到,继续等待
pass
except Exception as e:
error_msg = str(e)
self.logger.warning(f"设备查找测量结束按钮时出现异常: {error_msg}")
# 检测是否是UiAutomator2服务崩溃
if 'UiAutomator2 server' in error_msg and 'instrumentation process is not running' in error_msg and reinit_attempts < max_reinit_attempts:
reinit_attempts += 1
self.logger.info(f"设备检测到UiAutomator2服务崩溃尝试第 {reinit_attempts} 次重新初始化驱动")
# 尝试重新初始化驱动
if self._reinit_driver():
self.logger.info(f"设备驱动重新初始化成功")
else:
self.logger.error(f"设备驱动重新初始化失败")
# 继续尝试,而不是立即失败
# 等待一段时间后再次检查
time.sleep(3)
# 每30秒输出一次等待状态
if int(time.time() - start_time) % 30 == 0:
elapsed = int(time.time() - start_time)
self.logger.info(f"设备 {self.device_id} 已等待 {elapsed} 秒,仍在等待测量结束...")
self.logger.error(f"设备 {self.device_id} 等待测量结束按钮超时")
return False
except Exception as e:
self.logger.error(f"设备 {self.device_id} 等待测量结束时发生错误: {str(e)}")
return False
def _reinit_driver(self):
"""
重新初始化Appium驱动
Returns:
bool: 是否成功重新初始化
"""
try:
# 首先尝试关闭现有的驱动
if hasattr(self, 'driver') and self.driver:
try:
self.driver.quit()
except:
self.logger.warning("关闭现有驱动时出现异常")
# 导入必要的模块
from appium import webdriver
from appium.options.android import UiAutomator2Options
# 重新创建驱动配置
options = UiAutomator2Options()
options.platform_name = "Android"
options.device_name = self.device_id
options.app_package = "com.bjjw.cjgc"
options.app_activity = ".activity.LoginActivity"
options.automation_name = "UiAutomator2"
options.no_reset = True
options.auto_grant_permissions = True
options.new_command_timeout = 300
options.udid = self.device_id
# 重新连接驱动
self.logger.info(f"正在重新初始化设备 {self.device_id} 的驱动...")
self.driver = webdriver.Remote("http://localhost:4723", options=options)
# 重新初始化等待对象
from selenium.webdriver.support.ui import WebDriverWait
self.wait = WebDriverWait(self.driver, 1)
self.logger.info(f"设备 {self.device_id} 驱动重新初始化完成")
return True
except Exception as e:
self.logger.error(f"设备 {self.device_id} 驱动重新初始化失败: {str(e)}")
return False
def handle_confirmation_dialog(self, device_id, timeout=2):
"""
处理确认弹窗,点击""按钮
@@ -672,31 +562,68 @@ class ScreenshotPage:
"""
# 等待弹窗出现最多等待2秒
try:
dialog_message = WebDriverWait(self.driver, timeout).until(
EC.presence_of_element_located((AppiumBy.XPATH, "//android.widget.TextView[@text='是否退出测量界面?']"))
)
# dialog_message = WebDriverWait(self.driver, timeout).until(
# EC.presence_of_element_located((AppiumBy.XPATH, "//android.widget.TextView[@text='是否退出测量界面?']"))
# )
self.logger.info(f"设备 {device_id} 检测到确认弹窗")
# self.logger.info(f"设备 {device_id} 检测到确认弹窗")
# 查找并点击"是"按钮
confirm_button = self.driver.find_element(
AppiumBy.XPATH,
"//android.widget.Button[@text='' and @resource-id='android:id/button1']"
)
# # 查找并点击"是"按钮
# confirm_button = self.driver.find_element(
# AppiumBy.XPATH,
# "//android.widget.Button[@text='是' and @resource-id='android:id/button1']"
# )
if confirm_button.is_displayed() and confirm_button.is_enabled():
self.logger.info(f"设备 {device_id} 点击确认弹窗的''按钮")
confirm_button.click()
time.sleep(0.5)
return True
else:
self.logger.error(f"设备 {device_id} ''按钮不可点击")
return False
# if confirm_button.is_displayed() and confirm_button.is_enabled():
# self.logger.info(f"设备 {device_id} 点击确认弹窗的'是'按钮")
# confirm_button.click()
# time.sleep(0.5)
# return True
# else:
# self.logger.error(f"设备 {device_id} '是'按钮不可点击")
# return False
except TimeoutException:
# 超时未找到弹窗,认为没有弹窗,返回成功
self.logger.info(f"设备 {device_id} 等待 {timeout} 秒未发现确认弹窗,可能没有弹窗,返回成功")
return True
# except TimeoutException:
# # 超时未找到弹窗,认为没有弹窗,返回成功
# self.logger.info(f"设备 {device_id} 等待 {timeout} 秒未发现确认弹窗,可能没有弹窗,返回成功")
# return True
max_attempts = 2
for attempt in range(max_attempts):
try:
dialog_message = WebDriverWait(self.driver, timeout).until(
EC.presence_of_element_located((AppiumBy.XPATH, "//android.widget.TextView[@text='是否退出测量界面?']"))
)
self.logger.info(f"设备 {device_id} 检测到确认弹窗 (第 {attempt + 1} 次)")
# 查找并点击"是"按钮
confirm_button = self.driver.find_element(
AppiumBy.XPATH,
"//android.widget.Button[@text='' and @resource-id='android:id/button1']"
)
if confirm_button.is_displayed() and confirm_button.is_enabled():
self.logger.info(f"设备 {device_id} 点击确认弹窗的''按钮 (第 {attempt + 1} 次)")
confirm_button.click()
time.sleep(0.5)
# 如果是第一次尝试,继续检查是否还有弹窗
if attempt < max_attempts - 1:
self.logger.info(f"设备 {device_id} 等待 1 秒后检查是否还有弹窗")
time.sleep(0.5)
continue
return True
else:
self.logger.error(f"设备 {device_id} ''按钮不可点击")
return False
except TimeoutException:
# 超时未找到弹窗,认为没有弹窗,返回成功
self.logger.info(f"设备 {device_id} 等待 {timeout} 秒未发现确认弹窗,可能没有弹窗,返回成功")
return True
except Exception as e:
self.logger.error(f"设备 {device_id} 处理确认弹窗时出错: {str(e)}")
return False
def click_back_button(self, device_id):
"""点击手机系统返回按钮"""
@@ -765,7 +692,7 @@ class ScreenshotPage:
if confirm_button and confirm_button.is_displayed() and confirm_button.is_enabled():
self.logger.info(f"设备 {device_id} 点击确认弹窗的''按钮")
confirm_button.click()
time.sleep(1)
time.sleep(0.5)
# 验证弹窗是否消失
try:
@@ -785,7 +712,7 @@ class ScreenshotPage:
except Exception as e:
self.logger.warning(f"设备 {device_id} 查找确认弹窗时出现异常: {str(e)}")
time.sleep(1)
time.sleep(0.5)
self.logger.error(f"设备 {device_id} 等待返回确认弹窗超时")
return False
@@ -884,7 +811,7 @@ class ScreenshotPage:
# time.sleep(2)
self.logger.info(f"已点击平差处理按钮,检查是否在测量页面")
# 检测是否存在测量列表(修正逻辑)
# 检测是否存在测量列表
has_measurement_list = self.check_measurement_list(device_id)
if not has_measurement_list:
self.logger.info(f"设备 {device_id} 存在测量列表,重新执行平差流程")
@@ -943,7 +870,7 @@ class ScreenshotPage:
# 3. 验证是否成功返回到上一页面
time.sleep(1) # 等待页面跳转完成
time.sleep(0.5) # 等待页面跳转完成
# 可以添加页面验证逻辑,比如检查是否返回到预期的页面
# 这里可以根据实际应用添加特定的页面元素验证
@@ -967,7 +894,7 @@ class ScreenshotPage:
"""
try:
self.logger.info(f"设备 {device_id} 开始执行测量结束后的操作流程")
time.sleep(5)
time.sleep(0.5)
# 1. 下滑列表到最底端
if not self.scroll_list_to_bottom(device_id):
@@ -1071,7 +998,7 @@ class ScreenshotPage:
if self.click_last_spinner(device_id):
return True
self.logger.warning(f"设备 {device_id}{attempt + 1}次点击失败,准备重试")
time.sleep(1) # 重试前等待
time.sleep(0.5) # 重试前等待
except Exception as e:
self.logger.error(f"设备 {device_id}{attempt + 1}次尝试失败: {str(e)}")
@@ -1133,7 +1060,8 @@ class ScreenshotPage:
new_driver, new_wait = reconnect_driver(actual_device_id, self.driver)
if new_driver:
self.driver = new_driver
self.wait = new_wait
# self.wait = new_wait
self.wait = WebDriverWait(self.driver, 2)
self.logger.info(f"设备 {actual_device_id} 驱动重连成功")
else:
self.logger.error(f"设备 {actual_device_id} 驱动重连失败")
@@ -1189,8 +1117,8 @@ class ScreenshotPage:
retry_count += 1
if retry_count < max_retries:
self.logger.info(f"设备 {device_id} 将在1秒后进行第{retry_count+1}次重试")
time.sleep(1) # 等待1秒后重试
self.logger.info(f"设备 {device_id} 将在0.5秒后进行第{retry_count+1}次重试")
time.sleep(0.5) # 等待0.5秒后重试
self.logger.error(f"设备 {device_id} 经过{max_retries}次重试后仍无法展开下拉菜单")
return False
@@ -1222,7 +1150,7 @@ class ScreenshotPage:
'percent': 0.5
})
time.sleep(1)
time.sleep(0.5)
self.logger.info(f"设备 {device_id} 额外下滑完成")
return True
@@ -1343,8 +1271,10 @@ class ScreenshotPage:
# 检查GLOBAL_UPLOAD_BREAKPOINT_DICT是否为空如果为空则初始化一些测试数据
if not global_variable.get_upload_breakpoint_dict():
self.logger.warning("global_variable.GLOBAL_UPLOAD_BREAKPOINT_DICT为空正在初始化测试数据")
global_variable.set_upload_breakpoint_dict({'CDWZQ-2标-龙骨湾右线大桥-0-7号墩-平原': 'L156372', 'CDWZQ-2标-蓝家湾特大 桥-31-31-平原': 'L159206'})
self.logger.warning("上传列表为空,无法执行平差操作")
return False
# global_variable.set_upload_breakpoint_dict({'CDWZQ-2标-龙骨湾右线大桥-0-7号墩-平原': 'L156372', 'CDWZQ-2标-蓝家湾特大 桥-31-31-平原': 'L159206'})
breakpoint_names = list(global_variable.get_upload_breakpoint_dict().keys())
processed_breakpoints = []
@@ -1450,23 +1380,4 @@ class ScreenshotPage:
self.logger.info(f"等待10秒后重试...")
time.sleep(10)
return False
def run_automation_test(self):
# 滑动列表到底部
if not self.scroll_list_to_bottom(self.device_id):
self.logger.error(f"设备 {self.device_id} 下滑列表到底部失败")
return False
# 2. 点击最后一个spinner
if not self.click_last_spinner_with_retry(self.device_id):
self.logger.error(f"设备 {self.device_id} 点击最后一个spinner失败")
return False
# 3. 再下滑一次
if not self.scroll_down_once(self.device_id):
self.logger.warning(f"设备 {self.device_id} 再次下滑失败,但继续执行")
# 4. 点击平差处理按钮
if not self.click_adjustment_button(self.device_id):
self.logger.error(f"设备 {self.device_id} 点击平差处理按钮失败")
return False
return False