import time from framework.core.base_page import BasePage from framework.core.logger import get_logger logger = get_logger("ThreeDAssetsPage") class ThreeDAssetsPage(BasePage): """3D资产页面 POM - 包含资产包进入与数据新增逻辑""" MENU_TEXT = "3D资产" def __init__(self, page): self.page = page def navigate_to(self): """进入3D资产页面""" logger.info("正在切换到3D资产页面...") self.smart_click(self.MENU_TEXT) time.sleep(2) def enter_asset_package(self, package_name="ui_test"): """进入指定的资产包""" logger.info(f"📂 正在寻找并进入资产包: {package_name}") # 在资产包列表中找到对应名称的项进行点击 selector = f"div.p-card:has-text('{package_name}')" try: self.page.wait_for_selector(selector, timeout=10000) self.page.click(selector) logger.info(f"✅ 已进入资产包: {package_name}") # 等待渲染加载 time.sleep(2) return True except Exception as e: logger.error(f"❌ 无法找到资产包 {package_name}: {e}") return False def add_asset_data(self, asset_name): """执行[新增数据]流程""" logger.info(f"➕ 准备为资产包新增 3D 数据: {asset_name}") # 1. 点击[新增数据]按钮 add_btn = self.page.locator("button:has-text('新增数据')") add_btn.click() time.sleep(2) # 2. 点击路径选择区域 (图中带有'请选择包含模型文件的文件夹'占位符的区域) logger.info("🗺️ 点击路径选择区域...") path_trigger = self.page.locator("div.cursor-pointer:has-text('请选择包含模型文件的文件夹')") path_trigger.click() time.sleep(2) # 3. 在路径弹窗中操作 logger.info("🗂️ 在弹窗中选择 3D 生成目录...") # 点击左侧目录: 3d生成(勿删) folder_root = self.page.locator("span:has-text('3d生成(勿删)')") folder_root.click() time.sleep(2) # 等待列表渲染 # 4. 找到刚才生成的资产名称并勾选 logger.info(f"📍 寻找并勾选资产文件夹: {asset_name}") try: # 找到包含该名称的一行 asset_row = self.page.locator(f"div.flex:has(span:has-text('{asset_name}'))").last # 只点击行会高亮但不会勾选,需点击前面的 span 触发 checkbox_trigger = asset_row.locator("span").first checkbox_trigger.click() # 检测是否勾选成功 (类名中出现 checked) time.sleep(1) is_checked = self.page.locator(f"div.flex:has(span:has-text('{asset_name}'))").last.locator(".p-checkbox-checked").is_visible() if is_checked: logger.info(f"✅ 资产 {asset_name} 勾选状态确认成功") else: logger.warning(f"⚠️ 无法检测到勾选类名,尝试通过文字补偿点击第 1 个 span") asset_row.locator(f"span:has-text('{asset_name}')").first.click() except Exception as e: logger.error(f"❌ 勾选流程异常: {e}") # 5. 点击路径弹窗底部确定按钮 (修正:层级定位,解决点不中的问题) logger.info("⏳ 点击路径选择器[确定]按钮...") # 分层:在“选择文件”弹窗内寻找确定 file_picker_dialog = self.page.locator(".p-dialog:has-text('选择文件')") confirm_path_btn = file_picker_dialog.locator("button:has-text('确定')").last confirm_path_btn.wait_for(state="visible", timeout=5000) confirm_path_btn.scroll_into_view_if_needed() confirm_path_btn.click() logger.info("✅ 路径跳转弹窗已关闭") time.sleep(2) # 6. 继续处理新增数据弹窗 logger.info("💾 正在确认[新增3D资产数据]弹窗...") add_data_dialog = self.page.locator(".p-dialog:has-text('新增3D资产数据')") # 探测新增数据弹窗内是否已有数据 (校验) if "已选择1项" in self.page.content() or asset_name in self.page.content(): logger.info("📊 校验成功:新增数据弹窗已加载选中数据") else: logger.warning("⚠️ 未能在弹窗中明确校验到选中项,继续尝试提交") # 7. 点击新增数据弹窗的最终确定按钮 final_confirm_btn = add_data_dialog.locator("button:has-text('确定')").last final_confirm_btn.scroll_into_view_if_needed() final_confirm_btn.click() logger.info("🎉 3D 资产数据新增流程全部完成") time.sleep(3) # 等待列表回屏加载 return True def verify_asset_and_preview(self, asset_name): """校验资产包列表是否存在刚创建的资产,并查看预览""" logger.info(f"🔍 正在列表中核实资产: {asset_name}") # 1. 在列表中寻找该资产卡片并点击 asset_card = self.page.locator(f"div.p-card:has-text('{asset_name}')").first try: asset_card.wait_for(state="visible", timeout=10000) logger.info(f"✅ 找到资产卡片: {asset_name},准备查看预览") asset_card.click() except Exception as e: logger.error(f"❌ 列表中未发现资产 {asset_name}: {e}") return False # 2. 等待弹窗渲染加载 (model-viewer 等元素) logger.info("🖥️ 等待 3D 模型渲染预览渲染...") try: # 这里的 model-viewer 或特定的容器是渲染完成的标志 self.page.wait_for_selector("model-viewer, div.userInput.show", timeout=15000) logger.info("✨ 3D 模型预览已正常渲染") time.sleep(2) # 3. 点击右上角的 X 关闭预览 close_btn = self.page.locator("i.pi-times").first close_btn.click() logger.info("✅ 预览弹窗已关闭") return True except Exception as e: logger.error(f"❌ 预览渲染失败或无法关闭: {e}") return False def check_source_files(self): """点击右上角[源文件查看]并校验侧边栏""" logger.info("📂 点击[源文件查看]按钮...") source_btn = self.page.locator("button:has-text('源文件查看')") source_btn.click() # 等待侧边栏数据加载 logger.info("⏳ 等待侧边栏数据加载...") try: # 侧边栏通常是一个 p-sidebar 或包含资产文件结构的容器 self.page.wait_for_selector(".p-sidebar, div:has-text('源文件')", timeout=10000) time.sleep(2) # 点击右下角的关闭按钮 logger.info("🚪 点击侧边栏[关闭]按钮...") close_btn = self.page.locator("button:has-text('关闭')").last close_btn.click() logger.info("✅ 源文件侧边栏已关闭") return True except Exception as e: logger.error(f"❌ 源文件查看流程异常: {e}") return False