# test_more_download_page.py 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 import logging import time class MoreDownloadPage: def __init__(self, driver, wait,device_id): self.driver = driver self.wait = wait self.device_id = device_id self.logger = logging.getLogger(__name__) def is_on_more_download_page(self): """通过下载历史数据按钮来判断是否在更多下载页面""" try: # 使用下载历史数据按钮的resource-id来检查 download_history_locator = (AppiumBy.ID, "com.bjjw.cjgc:id/download_history") self.wait.until(EC.presence_of_element_located(download_history_locator)) self.logger.info("已确认在更多下载页面") return True except TimeoutException: self.logger.warning("未找到下载历史数据按钮,不在更多下载页面") return False except Exception as e: self.logger.error(f"检查更多下载页面时发生意外错误: {str(e)}") return False def click_download_button(self): """点击下载按钮""" try: # 点击下载历史数据按钮 download_button = self.wait.until( EC.element_to_be_clickable((AppiumBy.ID, "com.bjjw.cjgc:id/download_history")) ) download_button.click() self.logger.info("已点击下载历史数据按钮") # 等待下载操作开始 # time.sleep(3) return True except TimeoutException: self.logger.error("等待下载按钮可点击超时") return False except Exception as e: self.logger.error(f"点击下载按钮时出错: {str(e)}") return False def click_download_original_data(self): """点击下载原始数据按钮并处理日期选择""" try: # 点击下载原始数据按钮 download_original_btn = self.wait.until( EC.element_to_be_clickable((AppiumBy.ID, "com.bjjw.cjgc:id/download_org")) ) download_original_btn.click() self.logger.info("已点击下载原始数据按钮") # 等待日期选择弹窗出现 # time.sleep(2) # 点击选择开始日期 start_date_btn = self.wait.until( EC.element_to_be_clickable((AppiumBy.ID, "com.bjjw.cjgc:id/date")) ) start_date_btn.click() self.logger.info("已点击选择开始日期") # 等待日期选择器出现 # time.sleep(2) # 滑动年份选择器 - 向上滑动1/5的距离 if not self._swipe_year_wheel(): self.logger.error("滑动年份选择器失败") return False # 点击日期选择器的确定按钮 confirm_btn = self.wait.until( EC.element_to_be_clickable((AppiumBy.ID, "com.bjjw.cjgc:id/okBtn")) ) confirm_btn.click() self.logger.info("已确认日期选择") # 等待日期选择器关闭 # time.sleep(2) # 假设弹窗有确定按钮,点击它开始下载 try: # 尝试查找并点击下载弹窗的确定按钮 download_confirm_btn = WebDriverWait(self.driver, 5).until( EC.element_to_be_clickable((AppiumBy.XPATH, "//android.widget.Button[contains(@text, '确定') or contains(@text, '下载')]")) ) download_confirm_btn.click() self.logger.info("已点击下载确认按钮") except TimeoutException: self.logger.warning("未找到下载确认按钮,可能不需要确认") # 等待下载开始 # time.sleep(3) return True except TimeoutException: self.logger.error("等待下载原始数据按钮可点击超时") return False except Exception as e: self.logger.error(f"点击下载原始数据时出错: {str(e)}") return False def click_download_result_data(self): """点击下载成果数据按钮并处理日期选择""" try: # 点击下载成果数据按钮 download_result_btn = self.wait.until( EC.element_to_be_clickable((AppiumBy.ID, "com.bjjw.cjgc:id/download_result")) ) download_result_btn.click() self.logger.info("已点击下载成果数据按钮") # 等待日期选择弹窗出现 # time.sleep(2) # 点击选择开始日期 start_date_btn = self.wait.until( EC.element_to_be_clickable((AppiumBy.ID, "com.bjjw.cjgc:id/date")) ) start_date_btn.click() self.logger.info("已点击选择开始日期") # 等待日期选择器出现 # time.sleep(2) # 滑动年份选择器 - 向上滑动1/5的距离 if not self._swipe_year_wheel(): self.logger.error("滑动年份选择器失败") return False # 点击日期选择器的确定按钮 confirm_btn = self.wait.until( EC.element_to_be_clickable((AppiumBy.ID, "com.bjjw.cjgc:id/okBtn")) ) confirm_btn.click() self.logger.info("已确认日期选择") # 等待日期选择器关闭 # time.sleep(2) # 假设弹窗有确定按钮,点击它开始下载 try: # 尝试查找并点击下载弹窗的确定按钮 download_confirm_btn = WebDriverWait(self.driver, 5).until( EC.element_to_be_clickable((AppiumBy.XPATH, "//android.widget.Button[contains(@text, '确定') or contains(@text, '下载')]")) ) download_confirm_btn.click() self.logger.info("已点击下载确认按钮") except TimeoutException: self.logger.warning("未找到下载确认按钮,可能不需要确认") # 等待下载开始 # time.sleep(3) return True except TimeoutException: self.logger.error("等待下载成果数据按钮可点击超时") return False except Exception as e: self.logger.error(f"点击下载成果数据时出错: {str(e)}") return False def _swipe_year_wheel(self): """滑动年份选择器的滚轮""" try: # 获取年份选择器滚轮元素 year_wheel = self.driver.find_element(AppiumBy.ID, "com.bjjw.cjgc:id/wheelView1") # 获取滚轮的位置和尺寸 location = year_wheel.location size = year_wheel.size # 计算滚轮中心点坐标 center_x = location['x'] + size['width'] // 2 center_y = location['y'] + size['height'] // 2 # 计算滑动距离 - 滚轮高度的1/5 swipe_distance = size['height'] // 5 # 执行滑动操作 - 从中心向上滑动1/5高度 self.driver.swipe(center_x, center_y - swipe_distance, center_x, center_y, 500) self.logger.info("已滑动年份选择器") return True except Exception as e: self.logger.error(f"滑动年份选择器时出错: {str(e)}") return False def wait_for_loading_dialog(self, timeout=900): """ 检查特定结构的加载弹窗的出现和消失 参数: timeout: 最大等待时间,默认10分钟(600秒) 返回: bool: 如果加载弹窗出现并消失返回True,否则返回False """ try: self.logger.info("开始检查加载弹窗...") # 首先检查加载弹窗是否出现 start_time = time.time() loading_appeared = False # 等待加载弹窗出现(最多等待30秒) while time.time() - start_time < 30: try: # 根据提供的结构查找加载弹窗 # 查找包含ProgressBar和"loading..."文本的弹窗 loading_indicators = [ (AppiumBy.XPATH, "//android.widget.FrameLayout[@resource-id='android:id/content']/android.widget.LinearLayout[@resource-id='android:id/parentPanel']//android.widget.ProgressBar"), (AppiumBy.XPATH, "//android.widget.TextView[@resource-id='android:id/message' and @text='loading...']"), (AppiumBy.XPATH, "//android.widget.FrameLayout[@resource-id='android:id/content']//android.widget.ProgressBar"), (AppiumBy.XPATH, "//*[contains(@text, 'loading...')]") ] for by, value in loading_indicators: try: element = self.driver.find_element(by, value) if element.is_displayed(): loading_appeared = True self.logger.info("数据下载已开始") self.logger.info("检测到加载弹窗出现") break except: continue if loading_appeared: break except Exception as e: pass time.sleep(1) # 如果加载弹窗没有出现,直接返回True if not loading_appeared: self.logger.info("未检测到加载弹窗,继续执行") return True # 等待加载弹窗消失 self.logger.info("等待加载弹窗消失...") disappearance_start_time = time.time() while time.time() - disappearance_start_time < timeout: try: # 检查加载弹窗是否还存在 loading_still_exists = False for by, value in loading_indicators: try: element = self.driver.find_element(by, value) if element.is_displayed(): loading_still_exists = True break except: continue if not loading_still_exists: self.logger.info("加载弹窗已消失") return True # 每1分钟记录一次状态 if int(time.time() - disappearance_start_time) % 60 == 0: elapsed_time = int(time.time() - disappearance_start_time) self.logger.info(f"加载弹窗仍在显示,已等待{elapsed_time//60}分钟") except Exception as e: # 如果出现异常,可能弹窗已经消失 self.logger.info("加载弹窗可能已消失") return True time.sleep(1) # 如果超时,记录错误并返回False self.logger.error(f"加载弹窗在{timeout}秒后仍未消失") return False except Exception as e: self.logger.error(f"检查加载弹窗时出错: {str(e)}") return False def more_download_page_manager(self): """执行更多下载页面管理操作""" try: self.logger.info("开始执行更多下载页面操作") # 检查是否在更多下载页面 if not self.is_on_more_download_page(): self.logger.error("不在更多下载页面") return False # 点击下载历史数据按钮 if not self.click_download_button(): self.logger.error("点击下载历史数据按钮失败") return False # 等待下载历史数据页面加载完成 # time.sleep(3) # 点击下载原始数据按钮 if not self.click_download_original_data(): self.logger.error("点击下载原始数据按钮失败") return False # 等待下载操作完成 time.sleep(1) # 使用wait_for_loading_dialog函数等待下载过程中的加载弹窗消失 if not self.wait_for_loading_dialog(): self.logger.warning("下载过程中的加载弹窗未在预期时间内消失,但操作已完成") # 等待一段时间,确保原始数据下载完成 time.sleep(1) # 点击下载成果数据按钮 if not self.click_download_result_data(): self.logger.error("点击下载成果数据按钮失败") return False # 使用wait_for_loading_dialog函数等待下载过程中的加载弹窗消失 if not self.wait_for_loading_dialog(): self.logger.warning("成果数据下载过程中的加载弹窗未在预期时间内消失,但操作已完成") self.logger.info("更多下载页面操作执行完成") return True except Exception as e: self.logger.error(f"执行更多下载页面操作时出错: {str(e)}") return False