fix(yunda): 导出面板适配 Element UI 改版
韵达导出面板从 jQuery(.allRight/#submitbutton) 改版为 Element UI,应到/实到导出均卡在全选字段步骤。 - actual/expected 改 Element UI 交互:全选 → 向右转移(el-icon-d-arrow-right) → 导出(el-icon-download) → 等 el-loading-mask → el-message-box 成功提示 → 确定 - 新增 _resolve_export_frame() 探测导出 iframe(实到=myFrame、应到=target1),都未命中时 dump 面板内 iframe 名便于排查 - 外层 layui-layer 弹层、查询、切导出服务下载逻辑不变 验证:韵达应到 49 条 / 实到 141 条下载成功。 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -77,6 +77,35 @@ def _remove_if_exists(path):
|
||||
pass
|
||||
|
||||
|
||||
def _resolve_export_frame(ws_frame):
|
||||
"""定位韵达数据导出面板内嵌的 iframe。
|
||||
|
||||
韵达改版后导出面板换用 Element UI(全选/向右转移/导出按钮)。实到流程的面板
|
||||
iframe 名为 myFrame(已验证);应到流程历史上为 target1。这里短超时轮流探测,
|
||||
返回首个出现「全选」按钮的 frame;都未命中则 dump 面板内所有 iframe 名便于排查。
|
||||
"""
|
||||
for name in ("myFrame", "target1"):
|
||||
frame = ws_frame.frame_locator(f'iframe[name="{name}"]')
|
||||
try:
|
||||
frame.locator("button.el-button", has_text="全选").first.wait_for(
|
||||
state="visible", timeout=5000
|
||||
)
|
||||
print(f" [导出iframe] 命中 iframe[name={name}]")
|
||||
return frame
|
||||
except Exception:
|
||||
continue
|
||||
try:
|
||||
names = ws_frame.locator("iframe").evaluate_all(
|
||||
"els => els.map(e => e.name || '(无name)')"
|
||||
)
|
||||
print(
|
||||
f" [导出iframe] myFrame/target1 均未命中全选;面板 iframe 名: {names}"
|
||||
)
|
||||
except Exception as e:
|
||||
print(f" [导出iframe] dump 失败: {e}")
|
||||
return ws_frame.frame_locator('iframe[name="myFrame"]')
|
||||
|
||||
|
||||
def yunda_login(page):
|
||||
"""韵达自动登录:未登录则填充表单并提交,已登录则跳过。"""
|
||||
print(">> 正在检查韵达登录状态...")
|
||||
@@ -274,8 +303,11 @@ def yunda_expected_download_impl(page):
|
||||
ws_frame.locator("#docSum").wait_for(state="visible", timeout=15000)
|
||||
page.wait_for_timeout(500)
|
||||
|
||||
# 导出弹窗双层重试:外层重新打开面板,内层重新提交。
|
||||
# 区分字段漏选(补点全选)与字段列表消失(重新打开面板)。
|
||||
# 导出弹窗重试:外层重新打开面板(最多 3 次)。
|
||||
# 韵达站点已将导出面板从 jQuery(.allRight/#submitbutton) 改版为 Element UI
|
||||
# (与实到流程同一导出组件,iframe=myFrame):
|
||||
# 全选(button“全选”) → 向右转移(i.el-icon-d-arrow-right) → 导出(i.el-icon-download)
|
||||
# → 正在导出中(.el-loading-mask) → 成功提示(.el-message-box 导出任务建立成功) → 确定
|
||||
task_success = False
|
||||
for major_attempt in range(3):
|
||||
print(f" >> 正在打开数据导出面板 (尝试 {major_attempt + 1}/3)...")
|
||||
@@ -285,74 +317,61 @@ def yunda_expected_download_impl(page):
|
||||
state="visible", timeout=15000
|
||||
)
|
||||
|
||||
export_frame = ws_frame.frame_locator('iframe[name="target1"]')
|
||||
export_frame = _resolve_export_frame(ws_frame)
|
||||
|
||||
try:
|
||||
# 校验字段列表是否加载完成(以“交接单号”为标志)
|
||||
export_frame.get_by_text("交接单号").first.wait_for(
|
||||
state="visible", timeout=3000
|
||||
)
|
||||
# 校验 Element UI 字段选择区是否加载完成(以「全选」按钮就绪为标志)
|
||||
export_frame.locator(
|
||||
"button.el-button", has_text="全选"
|
||||
).first.wait_for(state="visible", timeout=8000)
|
||||
except Exception:
|
||||
print(" ⚠️ 字段列表未加载,关闭面板后重试...")
|
||||
print(" ⚠️ 导出面板字段区未加载,关闭面板后重试...")
|
||||
ws_frame.locator(".layui-layer-close1").click()
|
||||
page.wait_for_timeout(1000)
|
||||
continue
|
||||
|
||||
export_frame.locator(".allRight").click()
|
||||
print(" -> 全选字段并向右转移...")
|
||||
export_frame.locator("button.el-button", has_text="全选").first.click()
|
||||
page.wait_for_timeout(400)
|
||||
export_frame.locator(
|
||||
"button.el-button:has(i.el-icon-d-arrow-right)"
|
||||
).first.click()
|
||||
page.wait_for_timeout(500)
|
||||
|
||||
inner_success = False
|
||||
needs_reopen = False
|
||||
|
||||
print(" -> 正在提交导出任务...")
|
||||
for attempt in range(4):
|
||||
export_frame.locator("#submitbutton", has_text="导出数据").click()
|
||||
confirm_link = export_frame.get_by_role("link", name="确定")
|
||||
try:
|
||||
confirm_link.wait_for(state="visible", timeout=6000)
|
||||
if export_frame.get_by_text("导出任务建立成功").is_visible():
|
||||
print(" ✅ 导出任务已建立成功。")
|
||||
confirm_link.click()
|
||||
inner_success = True
|
||||
break
|
||||
elif export_frame.get_by_text(
|
||||
"请选择格式相应的导出字段"
|
||||
).is_visible():
|
||||
confirm_link.click()
|
||||
page.wait_for_timeout(500)
|
||||
export_frame.locator(
|
||||
"button.el-button:has(i.el-icon-download)"
|
||||
).first.click()
|
||||
|
||||
# 区分:字段漏选 还是 字段列表消失
|
||||
if export_frame.get_by_text("交接单号").first.is_visible():
|
||||
print(
|
||||
" ⚠️ 检测到未选择字段(字段列表仍在),重新点击全选..."
|
||||
)
|
||||
export_frame.locator(".allRight").click()
|
||||
page.wait_for_timeout(500)
|
||||
else:
|
||||
print(
|
||||
" ⚠️ 字段列表异常消失,重新打开导出面板..."
|
||||
)
|
||||
needs_reopen = True
|
||||
break # 跳出内层循环,重新打开面板
|
||||
else:
|
||||
confirm_link.click()
|
||||
page.wait_for_timeout(1000)
|
||||
# 等待「正在导出中」遮罩出现并消失
|
||||
loading = export_frame.locator(".el-loading-mask").first
|
||||
try:
|
||||
loading.wait_for(state="visible", timeout=5000)
|
||||
loading.wait_for(state="hidden", timeout=60000)
|
||||
except Exception:
|
||||
page.wait_for_timeout(1000)
|
||||
pass
|
||||
|
||||
# 等待结果提示并判定
|
||||
inner_success = False
|
||||
try:
|
||||
msg_box = export_frame.locator(".el-message-box.my-alert").first
|
||||
msg_box.wait_for(state="visible", timeout=30000)
|
||||
if msg_box.get_by_text("导出任务建立成功").is_visible():
|
||||
print(" ✅ 导出任务已建立成功。")
|
||||
inner_success = True
|
||||
else:
|
||||
print(" ⚠️ 导出结果提示非成功状态,将重试。")
|
||||
msg_box.locator("button.el-button", has_text="确定").first.click()
|
||||
page.wait_for_timeout(500)
|
||||
except Exception:
|
||||
print(" ⚠️ 未检测到导出结果提示,将重试。")
|
||||
|
||||
ws_frame.locator(".layui-layer-close1").click()
|
||||
page.wait_for_timeout(500)
|
||||
|
||||
if inner_success:
|
||||
task_success = True
|
||||
ws_frame.locator(".layui-layer-close1").click()
|
||||
page.wait_for_timeout(500)
|
||||
break # 跳出外层循环,继续后续步骤
|
||||
elif needs_reopen:
|
||||
ws_frame.locator(".layui-layer-close1").click()
|
||||
page.wait_for_timeout(1000)
|
||||
continue # 重新打开面板
|
||||
else:
|
||||
ws_frame.locator(".layui-layer-close1").click()
|
||||
page.wait_for_timeout(1000)
|
||||
continue
|
||||
break
|
||||
|
||||
if not task_success:
|
||||
raise RuntimeError("多次重试后仍未能建立应到数据离线任务。")
|
||||
@@ -497,8 +516,10 @@ def yunda_actual_download_impl(page):
|
||||
).click()
|
||||
return
|
||||
|
||||
# 导出弹窗双层重试:外层重新打开面板,内层重新提交。
|
||||
# 区分字段漏选(补点全选)与字段列表消失(重新打开面板)。
|
||||
# 导出弹窗重试:外层重新打开面板(最多 3 次)。
|
||||
# 韵达站点已将导出面板从 jQuery(.allRight/#submitbutton) 改版为 Element UI:
|
||||
# 全选(button“全选”) → 向右转移(i.el-icon-d-arrow-right) → 导出(i.el-icon-download)
|
||||
# → 正在导出中(.el-loading-mask) → 成功提示(.el-message-box 导出任务建立成功) → 确定
|
||||
print(">> 正在发起导出...")
|
||||
task_success = False
|
||||
|
||||
@@ -512,69 +533,58 @@ def yunda_actual_download_impl(page):
|
||||
export_frame = ws_frame.frame_locator('iframe[name="myFrame"]')
|
||||
|
||||
try:
|
||||
# 校验字段列表是否加载完成(以“扫描类型”为标志)
|
||||
export_frame.get_by_text("扫描类型").first.wait_for(
|
||||
state="visible", timeout=3000
|
||||
)
|
||||
# 校验 Element UI 字段选择区是否加载完成(以「全选」按钮就绪为标志)
|
||||
export_frame.locator(
|
||||
"button.el-button", has_text="全选"
|
||||
).first.wait_for(state="visible", timeout=8000)
|
||||
except Exception:
|
||||
print(" ⚠️ 字段列表未加载,关闭面板后重试...")
|
||||
print(" ⚠️ 导出面板字段区未加载,关闭面板后重试...")
|
||||
ws_frame.locator(".layui-layer-close1").click()
|
||||
page.wait_for_timeout(1000)
|
||||
continue
|
||||
|
||||
export_frame.locator(".allRight").click()
|
||||
print(" -> 全选字段并向右转移...")
|
||||
export_frame.locator("button.el-button", has_text="全选").first.click()
|
||||
page.wait_for_timeout(400)
|
||||
export_frame.locator(
|
||||
"button.el-button:has(i.el-icon-d-arrow-right)"
|
||||
).first.click()
|
||||
page.wait_for_timeout(500)
|
||||
|
||||
inner_success = False
|
||||
needs_reopen = False
|
||||
|
||||
print(" -> 正在提交导出任务...")
|
||||
for attempt in range(4):
|
||||
export_frame.locator("#submitbutton", has_text="导出数据").click()
|
||||
confirm_link = export_frame.get_by_role("link", name="确定")
|
||||
try:
|
||||
confirm_link.wait_for(state="visible", timeout=6000)
|
||||
if export_frame.get_by_text("导出任务建立成功").is_visible():
|
||||
print(" ✅ 导出任务已建立成功。")
|
||||
confirm_link.click()
|
||||
inner_success = True
|
||||
break
|
||||
elif export_frame.get_by_text(
|
||||
"请选择格式相应的导出字段"
|
||||
).is_visible():
|
||||
confirm_link.click()
|
||||
page.wait_for_timeout(500)
|
||||
export_frame.locator(
|
||||
"button.el-button:has(i.el-icon-download)"
|
||||
).first.click()
|
||||
|
||||
# 区分:字段漏选 还是 字段列表消失
|
||||
if export_frame.get_by_text("扫描类型").first.is_visible():
|
||||
print(
|
||||
" ⚠️ 检测到未选择字段(字段列表仍在),重新点击全选..."
|
||||
)
|
||||
export_frame.locator(".allRight").click()
|
||||
page.wait_for_timeout(500)
|
||||
else:
|
||||
print(" ⚠️ 字段列表异常消失,重新打开导出面板...")
|
||||
needs_reopen = True
|
||||
break
|
||||
else:
|
||||
confirm_link.click()
|
||||
page.wait_for_timeout(1000)
|
||||
# 等待「正在导出中」遮罩出现并消失
|
||||
loading = export_frame.locator(".el-loading-mask").first
|
||||
try:
|
||||
loading.wait_for(state="visible", timeout=5000)
|
||||
loading.wait_for(state="hidden", timeout=60000)
|
||||
except Exception:
|
||||
page.wait_for_timeout(1000)
|
||||
pass
|
||||
|
||||
# 等待结果提示并判定
|
||||
inner_success = False
|
||||
try:
|
||||
msg_box = export_frame.locator(".el-message-box.my-alert").first
|
||||
msg_box.wait_for(state="visible", timeout=30000)
|
||||
if msg_box.get_by_text("导出任务建立成功").is_visible():
|
||||
print(" ✅ 导出任务已建立成功。")
|
||||
inner_success = True
|
||||
else:
|
||||
print(" ⚠️ 导出结果提示非成功状态,将重试。")
|
||||
msg_box.locator("button.el-button", has_text="确定").first.click()
|
||||
page.wait_for_timeout(500)
|
||||
except Exception:
|
||||
print(" ⚠️ 未检测到导出结果提示,将重试。")
|
||||
|
||||
ws_frame.locator(".layui-layer-close1").click()
|
||||
page.wait_for_timeout(500)
|
||||
|
||||
if inner_success:
|
||||
task_success = True
|
||||
ws_frame.locator(".layui-layer-close1").click()
|
||||
page.wait_for_timeout(500)
|
||||
break
|
||||
elif needs_reopen:
|
||||
ws_frame.locator(".layui-layer-close1").click()
|
||||
page.wait_for_timeout(1000)
|
||||
continue
|
||||
else:
|
||||
ws_frame.locator(".layui-layer-close1").click()
|
||||
page.wait_for_timeout(1000)
|
||||
continue
|
||||
|
||||
if not task_success:
|
||||
raise RuntimeError("多次重试后仍未能建立实到数据离线任务。")
|
||||
|
||||
Reference in New Issue
Block a user