feat(发布计划): 新增「校验页面」步骤(expect_el)—— 每一步先确认上一步真的完成了
用户要求:"进行每一步的时候先校验上一步有没有完成,比如相册界面肯定有特征,如果没有到相册界面
就出现执行,你看看怎么处理" → 方案 A:新增只做校验、不带副作用的步骤。
· tasks/generic/task.py:新步骤 expect_el
- 参数:特征元素选择器 / timeout(10) / what("在等什么") / on_missing
- on_missing:skip_rest(默认,**跳过本轮剩余步骤** —— 这一条不发、换下一个号) / notify / stop
- 为此加了 worker 级的 `_skip_rest`:_exec_steps 每步前检查,foreach_account 每轮复位
· 骨架:关键点击前各插一个 —— 相册页(//*[@text='所有照片']) → 素材已选中(desc 选择/预览)
→ 剪辑页(desc 文字/话题) → 发布页(含'添加标题'/'添加作品描述') → 发布按钮
· 通知:新增 task.page.mismatch(页面不对,本轮剩余步骤已跳过)
· 昵称选择器改**两版通吃**(实测 A06=40.7.0):xpath 联合
`//*[@resource-id="…:id/tkv"] | //*[@resource-id="…:id/tk+"]`
—— 40.7 是 tkv、40.6 是 tk+,联合在 40.7 上实测能读到名字;.env(dev)已改,切号入口两版同为 desc=切换账号
· 前端:编辑器面板 + 参数表单 + 发布页就地编辑字段表都认 expect_el
· 文档:TASK_DEV §3(27→28 种)+ §4.7("每步先校验上一步")、NOTIFY、research §七·补(40.7.0 对照表
+ 联合 xpath + 各页特征 + "别按坐标点页签"的坑)、.env.example
· 测试:新增 scripts/tests/test_expect_el.py(特征在/不在、三种 on_missing、选择器为空),全套 7 个用例通过
This commit is contained in:
+31
-8
@@ -500,6 +500,20 @@ def build_switch_step(label="切换账号(切到本次要发的那个名字)
|
||||
"on_login_page": "stop", "probability": 100}}
|
||||
|
||||
|
||||
def build_expect_step(label, sel_type, sel_val, what="", timeout=10,
|
||||
on_missing="skip_rest"):
|
||||
"""「校验页面」步骤:放在关键点击**前面**,确认上一步真的完成了(该页的特征元素在不在)。
|
||||
|
||||
等不到默认 `skip_rest`(跳过本轮剩余步骤 = 这一条不发、换下一个号),
|
||||
避免在错的页面上继续盲点。特征元素取实测值,见 doc/research/U2_ELEMENT_SELECTORS.md §七。
|
||||
"""
|
||||
return {"id": f"step_rel_exp_{uuid.uuid4().hex[:6]}", "type": "expect_el",
|
||||
"label": label,
|
||||
"params": {"selector_type": sel_type, "selector_value": sel_val,
|
||||
"timeout": timeout, "on_missing": on_missing,
|
||||
"what": what or label, "probability": 100}}
|
||||
|
||||
|
||||
def build_foreach_step(children=None, label="循环本机待发的号(一轮跑完,一直切到发完)"):
|
||||
"""「循环本机待发的号」容器步骤(`foreach_account`)—— 发布骨架的最外层。
|
||||
|
||||
@@ -581,20 +595,29 @@ def build_release_steps():
|
||||
clk("open", "⑨ 点击抖音底部「+」(实测可用;改版了重新抓)",
|
||||
"descriptionContains", "拍摄"),
|
||||
clk("album", "⑩ 点击「相册」(没命中的话用抓取元素选它)"),
|
||||
clk("video", "⑪ 点击第一个视频(刚推的排最前;抓一次就行)"),
|
||||
clk("next", "⑫ 点击「下一步」"),
|
||||
clk("input", "⑬ 点击标题框(抖音发布页的标题框:hint「添加标题」)"),
|
||||
# 关键点都先"校验页面":上一步没生效就别往下盲点(默认跳过本轮剩余 = 这一条不发)
|
||||
build_expect_step("⑪ 校验:应在相册页(看到「所有照片」)", "xpath",
|
||||
"//*[@text='所有照片']", "相册页(所有照片)", timeout=10),
|
||||
clk("video", "⑫ 点击第一个素材(刚推的排最前;抓一次就行)"),
|
||||
build_expect_step("⑬ 校验:素材应已选中(看到「选择/预览」)", "xpath",
|
||||
"//*[@content-desc='选择' or @content-desc='预览']", "素材已选中", timeout=10),
|
||||
clk("next", "⑭ 点击「下一步」"),
|
||||
build_expect_step("⑮ 校验:应在剪辑页(看到「文字/话题」工具)", "xpath",
|
||||
"//*[@content-desc='文字' or @content-desc='话题']", "剪辑页", timeout=12),
|
||||
clk("input", "⑯ 点击标题框(抖音发布页的标题框:hint「添加标题」)"),
|
||||
{"id": sid("title"), "type": "input_text",
|
||||
"label": "⑭ 填标题(自动取这一条计划的标题,会回读校验)",
|
||||
"label": "⑰ 填标题(自动取这一条计划的标题,会回读校验)",
|
||||
"params": {"text_source": "release_title", "release_topics": "",
|
||||
"clear_first": True, "mode": "random", "texts": "", "fixed_text": ""}},
|
||||
clk("body", "⑮ 点击正文框(发布页的描述框:hint「添加作品描述」)"),
|
||||
clk("body", "⑱ 点击正文框(发布页的描述框:hint「添加作品描述」)"),
|
||||
{"id": sid("bodytxt"), "type": "input_text",
|
||||
"label": "⑯ 填正文(自动取这一条计划的正文,会回读校验)",
|
||||
"label": "⑲ 填正文(自动取这一条计划的正文,会回读校验)",
|
||||
"params": {"text_source": "release_body", "release_topics": "",
|
||||
"clear_first": True, "mode": "random", "texts": "", "fixed_text": ""}},
|
||||
clk("publish", "⑰ 点击「发布」"),
|
||||
dict(build_mark_step("⑱ 标记发布结果(成功走这里;失败分支再放一个 result=failed)")),
|
||||
build_expect_step("⑳ 校验:应在发布页(看到「发布」按钮)", "xpath",
|
||||
"//*[@text='发布' or @content-desc='发布']", "发布页(发布按钮)", timeout=10),
|
||||
clk("publish", "㉑ 点击「发布」"),
|
||||
dict(build_mark_step("㉒ 标记发布结果(成功走这里;失败分支再放一个 result=failed)")),
|
||||
]
|
||||
# 循环体:切号 → 读名字 → 校验 → 推送 → 发布 → 标记。
|
||||
# `switch_account` 自己会先看"当前是不是已经是目标"(第一个号不用切),
|
||||
|
||||
Reference in New Issue
Block a user