chore: auto release commit (2026-09-15 01:27:04)
Some checks failed
技能自动化发布 / release (push) Failing after 4s
Some checks failed
技能自动化发布 / release (push) Failing after 4s
This commit is contained in:
@@ -529,6 +529,76 @@ def _fill_root_login(page) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def _fill_demo_on_spa_login(page) -> bool:
|
||||
"""v1.1.27:SPA 二级登录页(/industries/campus/smartcampus/login)
|
||||
input 默认**不预填**(与根域不同),必须主动 fill demo/123456 再点登录。
|
||||
|
||||
selector 优先级:
|
||||
- user: `#jc-user` → `input[type='tel']` → `input[autocomplete='username']`
|
||||
- pass: `#jc-pass` → `input[type='password']` → `input[autocomplete='current-password']`
|
||||
按钮文本优先级:Sign in → 登录 → Login → signin → submit[type]。
|
||||
|
||||
返回是否成功点登录按钮。
|
||||
"""
|
||||
# 找 user input
|
||||
user_loc = None
|
||||
for sel in ("#jc-user", "input[type='tel']", "input[autocomplete='username']"):
|
||||
loc = page.locator(sel).first
|
||||
if loc.count() > 0:
|
||||
user_loc = loc
|
||||
break
|
||||
if user_loc is None:
|
||||
logger.warning(
|
||||
"platform_collector._fill_demo_on_spa_login: 找不到 user input "
|
||||
"(#jc-user / tel / autocomplete=username 全 miss)"
|
||||
)
|
||||
return False
|
||||
|
||||
# 找 pass input
|
||||
pass_loc = None
|
||||
for sel in ("#jc-pass", "input[type='password']", "input[autocomplete='current-password']"):
|
||||
loc = page.locator(sel).first
|
||||
if loc.count() > 0:
|
||||
pass_loc = loc
|
||||
break
|
||||
if pass_loc is None:
|
||||
logger.warning(
|
||||
"platform_collector._fill_demo_on_spa_login: 找不到 pass input"
|
||||
)
|
||||
return False
|
||||
|
||||
user_loc.fill("demo")
|
||||
pass_loc.fill("123456")
|
||||
logger.info(
|
||||
"platform_collector: SPA 二级登录页 fill demo/123456 完成"
|
||||
)
|
||||
|
||||
# 找登录按钮
|
||||
btn = None
|
||||
btn_text_used = ""
|
||||
for txt in ("Sign in", "登录", "Login", "signin"):
|
||||
loc = page.locator(f"button:has-text('{txt}')").first
|
||||
if loc.count() > 0:
|
||||
btn = loc
|
||||
btn_text_used = txt
|
||||
break
|
||||
if btn is None:
|
||||
btn = page.locator("button[type='submit']").first
|
||||
btn_text_used = "submit"
|
||||
if btn is None or btn.count() == 0:
|
||||
logger.warning(
|
||||
"platform_collector._fill_demo_on_spa_login: 找不到登录按钮"
|
||||
)
|
||||
return False
|
||||
|
||||
logger.info(
|
||||
"platform_collector: SPA 二级登录页点 %s 按钮(demo/123456)",
|
||||
btn_text_used,
|
||||
)
|
||||
btn.click()
|
||||
return True
|
||||
|
||||
|
||||
def _click_campus_link(page) -> bool:
|
||||
"""在 /select 页面点智慧校园 tile,返回是否点中。"""
|
||||
link = page.locator("a[href*='/industries/campus']").first
|
||||
@@ -743,44 +813,52 @@ def collect_all(
|
||||
f"(请用 --show-browser 重试)"
|
||||
)
|
||||
|
||||
# 4. 登录完成 → 等 URL 真正稳定到 /app/ 或 /select(最多 30s,**不做任何操作**)
|
||||
# v1.1.22:sandbox 登录后会先跳 /select,再自动跳 /app/home,
|
||||
# 所以两个 URL 都算"SPA 已路由"
|
||||
if not _wait_for_url_stable(page, ("/app/", "/select"), max_wait_sec=30):
|
||||
# 4. v1.1.27:等 URL 跳到任一「SPA 已路由」状态(最多 30s,**不做任何操作**)
|
||||
# - /app/ = 已到 SPA 主页
|
||||
# - /select = sandbox 中间页
|
||||
# - /login 或 /signin = sandbox 又把人踢回登录页(根域登录后常见,
|
||||
# sandbox 会跳到 /industries/campus/smartcampus/login SPA 二级登录页)
|
||||
# - 如果 URL 跳到 login/signin,**立即**退出 30 秒等待(不再干等),
|
||||
# 让 4.5 处理。否则会等满 30 秒才发现要进 SPA 登录兜底,造成卡顿。
|
||||
spa_url_seen = False
|
||||
if not _wait_for_url_stable(
|
||||
page, ("/app/", "/select", "/login", "/signin"), max_wait_sec=30,
|
||||
):
|
||||
logger.warning(
|
||||
"platform_collector: 登录后 30s 内 URL 未稳定到 /app/或 /select(当前 URL=%s)",
|
||||
"platform_collector: 登录后 30s 内 URL 未稳定到 /app/、/select、"
|
||||
"/login 或 /signin(当前 URL=%s)",
|
||||
page.url,
|
||||
)
|
||||
# 不强行 reload —— 让用户决定是否手工刷新
|
||||
|
||||
# 4.5. v1.1.24:sandbox 可能登录后把人踢回 SPA 二级登录页
|
||||
# (/industries/campus/smartcampus/login)。如果 URL 落在
|
||||
# 这个二级登录页,再走一次 _try_auto_sign_in(已经扩展支持
|
||||
# 中文「登录」按钮);若 SPA 登录页 input 有预填账号 → 自动点;
|
||||
# 若 input 空 → 等用户输入并**自己点登录**(脚本不抢按钮)。
|
||||
# 4.5. v1.1.24/27:URL 落在 SPA 二级登录页 → 自动填 demo/123456 再登录
|
||||
# sandbox SPA 登录页 input 默认**不预填**(与根域不同),
|
||||
# 所以 _try_auto_sign_in 不会自动点 —— 必须显式 fill demo/123456。
|
||||
cur_url_after_stable = page.url.lower()
|
||||
if "/login" in cur_url_after_stable or "/signin" in cur_url_after_stable:
|
||||
logger.warning(
|
||||
"platform_collector: 登录后仍落在登录页(%s),"
|
||||
"v1.1.24 触发 SPA 二级登录兜底",
|
||||
"platform_collector: 登录后落在 SPA 二级登录页(%s),"
|
||||
"v1.1.27 触发 demo/123456 自动 fill",
|
||||
page.url,
|
||||
)
|
||||
spa_auto = _try_auto_sign_in(page, wait_input_sec=2)
|
||||
if spa_auto:
|
||||
spa_filled = _fill_demo_on_spa_login(page)
|
||||
if spa_filled:
|
||||
logger.info(
|
||||
"platform_collector: ✅ SPA 二级登录页已自动登录,"
|
||||
"等 URL 跳到 /app/ 或 /select"
|
||||
"platform_collector: ✅ SPA 二级登录页 demo/123456 自动填好,"
|
||||
"已点登录,等 URL 跳到 /app/ 或 /select"
|
||||
)
|
||||
_wait_for_url_stable(page, ("/app/", "/select"), max_wait_sec=30)
|
||||
elif not headless:
|
||||
if _wait_for_login_inputs_filled(page, wait_sec=human_wait_timeout):
|
||||
_wait_for_url_stable(page, ("/app/", "/select"), max_wait_sec=30)
|
||||
else:
|
||||
_wait_for_manual_login(page, wait_sec=human_wait_timeout)
|
||||
else:
|
||||
raise LoginTimeoutError(
|
||||
f"SPA 二级登录页 input 空且 headless 无法手工登录(URL={page.url})"
|
||||
)
|
||||
# demo fill 失败(input 不存在)→ 等用户手工输入
|
||||
if not headless:
|
||||
if _wait_for_login_inputs_filled(page, wait_sec=human_wait_timeout):
|
||||
_wait_for_url_stable(page, ("/app/", "/select"), max_wait_sec=30)
|
||||
else:
|
||||
_wait_for_manual_login(page, wait_sec=human_wait_timeout)
|
||||
else:
|
||||
raise LoginTimeoutError(
|
||||
f"SPA 二级登录页 demo fill 失败且 headless 无法手工登录"
|
||||
f"(URL={page.url})"
|
||||
)
|
||||
|
||||
# 5. v1.1.22:显式跳到 SPA_HOME_URL(/app/home),等侧边栏 link 出现
|
||||
# 避免 sandbox 在 /select 中间页时直接找 sidebar link 找不到
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"""
|
||||
|
||||
SKILL_SLUG = "alert-contract-expiring-hr"
|
||||
SKILL_VERSION = "1.1.26"
|
||||
SKILL_VERSION = "1.1.27"
|
||||
LOG_LOGGER_NAME = "openclaw.skill.alert_contract_expiring_hr"
|
||||
PLATFORM_KIT_MIN_VERSION = "1.2.11"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user