135 lines
5.1 KiB
Python
135 lines
5.1 KiB
Python
"""web_page 工具冒烟测试(fixture 本地页面,覆盖本次改动核心能力)。
|
|
|
|
运行: python Agent/tests/web_page/smoke_test.py
|
|
依赖: 无浏览器时自动分离启动(browser_control 逻辑)
|
|
"""
|
|
import http.server
|
|
import json
|
|
import sys
|
|
import threading
|
|
from pathlib import Path
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
sys.path.insert(0, str(HERE.parents[2] / "Agent" / "src"))
|
|
|
|
from agent.tools.web_page import WebPage as WebPageTool # noqa: E402
|
|
|
|
PORT = 8766
|
|
|
|
PASS = 0
|
|
FAIL = 0
|
|
|
|
|
|
def check(name: str, cond: bool, detail: str = "") -> None:
|
|
global PASS, FAIL
|
|
if cond:
|
|
PASS += 1
|
|
print(f"[PASS] {name}")
|
|
else:
|
|
FAIL += 1
|
|
print(f"[FAIL] {name} {detail}")
|
|
|
|
|
|
class NoCacheHandler(http.server.SimpleHTTPRequestHandler):
|
|
def end_headers(self):
|
|
self.send_header("Cache-Control", "no-store")
|
|
super().end_headers()
|
|
|
|
def log_message(self, *a):
|
|
pass
|
|
|
|
|
|
def serve() -> None:
|
|
handler = lambda *a, **kw: NoCacheHandler(*a, directory=str(HERE / "fixture"), **kw)
|
|
http.server.ThreadingHTTPServer(("127.0.0.1", PORT), handler).serve_forever()
|
|
|
|
|
|
def main() -> None:
|
|
threading.Thread(target=serve, daemon=True).start()
|
|
|
|
tool = WebPageTool()
|
|
|
|
def run(actions: list[dict]) -> str:
|
|
return tool._run(actions)[0]
|
|
|
|
# 1. 打开 fixture 页面
|
|
msg = run([{"action": "goto", "url": f"http://127.0.0.1:{PORT}/index.html"}])
|
|
check("goto fixture", "已打开" in msg, msg)
|
|
|
|
# 2. 登录区元素
|
|
msg = run([{"action": "snapshot"}])
|
|
check("快照含账户名", '"账户名"' in msg, msg[:200])
|
|
check("快照含密码", '"密码"' in msg)
|
|
check("快照含登录按钮", 'button "登录"' in msg)
|
|
|
|
# 3. 打开弹窗 → 层级断言
|
|
msg = run([
|
|
{"action": "click", "selector": "text=\"打开弹窗\""},
|
|
{"action": "wait", "wait_seconds": 0.3},
|
|
{"action": "snapshot"},
|
|
])
|
|
check("弹窗标注 [弹窗]", "[弹窗]" in msg, msg[:300])
|
|
check("弹窗含 Close", 'button "Close"' in msg)
|
|
check("弹窗含确认按钮", 'button "确认"' in msg)
|
|
|
|
# 4. 展开下拉 → 选项进快照 + 纯文本标题标注
|
|
msg = run([
|
|
{"action": "click", "selector": "text=\"请选择产品\"", "note": "展开下拉"},
|
|
{"action": "wait", "wait_seconds": 0.3},
|
|
{"action": "snapshot"},
|
|
])
|
|
check("纯文本容器标 [文本]", "[文本]" in msg, msg[:300])
|
|
check("下拉选项进快照", "意外险" in msg and "060003旅游意外伤害保险" in msg, msg[:400])
|
|
|
|
# 5. text= 精确匹配点击下拉选项
|
|
msg = run([{"action": "click", "selector": "text=\"意外险\"", "note": "选项"}])
|
|
check("text= 点选项成功", "已点击" in msg, msg)
|
|
msg = run([{"action": "eval_js", "js": "document.querySelector('.ant-select-selection').textContent"}])
|
|
check("下拉选中意外险", "意外险" in msg, msg)
|
|
|
|
# 6. date 动作:2005-07-09(年份面板需翻两个十年;先关闭弹窗避免遮挡)
|
|
msg = run([
|
|
{"action": "click", "selector": "text=\"Close\"", "note": "关弹窗"},
|
|
{"action": "wait", "wait_seconds": 0.3},
|
|
{"action": "date", "selector": "input.ant-calendar-picker-input", "value": "2005-07-09"},
|
|
])
|
|
check("date 动作成功", "已选择日期: 2005-07-09" in msg, msg)
|
|
msg = run([{"action": "eval_js", "js": "document.querySelector('.ant-calendar-picker-input').value"}])
|
|
check("date 写入输入框", "2005-07-09" in msg, msg)
|
|
|
|
# 7. shadow DOM 穿透
|
|
msg = run([{"action": "snapshot", "max_elements": 100}])
|
|
check("shadow DOM 按钮可见", "影子按钮" in msg, msg[:300])
|
|
|
|
# 8. text= 精确匹配失败 → 自动子串匹配报告真实候选
|
|
# (打开弹窗使下拉选项可见:text=旅游 精确匹配不到,子串候选含 060003旅游意外伤害保险)
|
|
msg = run([
|
|
{"action": "click", "selector": "text=\"打开弹窗\""},
|
|
{"action": "wait", "wait_seconds": 0.3},
|
|
{"action": "click", "selector": "text=旅游"},
|
|
])
|
|
check("text= 失败给出候选报告", "候选" in msg and "060003旅游" in msg, msg[:300])
|
|
|
|
# 9. 树节点:switcher 标 [展开],title 正常显示且可点击选中
|
|
msg = run([{"action": "snapshot", "max_elements": 200}])
|
|
check("树 switcher 标 [展开]", "[展开]" in msg, msg[:400])
|
|
check("树节点标题可见", "北京分公司车险管理部" in msg, msg[:400])
|
|
msg = run([
|
|
{"action": "click", "selector": "text=\"Close\"", "note": "关弹窗"},
|
|
{"action": "wait", "wait_seconds": 0.3},
|
|
{"action": "click", "selector": "text=\"北京分公司车险管理部\"", "note": "树节点标题"},
|
|
])
|
|
check("树节点标题可点击", "已点击" in msg, msg)
|
|
msg = run([{"action": "eval_js", "js": "document.getElementById('org-selected').textContent"}])
|
|
check("树节点点击选中生效", "已选: 北京分公司车险管理部" in msg, msg)
|
|
|
|
print()
|
|
if FAIL:
|
|
print(f"✗ {FAIL} 项失败 / {PASS} 项通过")
|
|
sys.exit(1)
|
|
print(f"全部通过 ✓({PASS} 项断言)")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|