164 lines
7.2 KiB
Python
164 lines
7.2 KiB
Python
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
|