test_s2_agents_frontend.py
3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env python3
"""S2 test: Agents frontend pages — /agents and /agent/<name> routes."""
import json, sys, subprocess
BASE = "http://127.0.0.1:5001"
passed = 0
failed = 0
def curl(path, method="GET", data=None):
cmd = ["curl", "-s", "-w", "\n%{http_code}", f"{BASE}{path}"]
if method == "POST" and data:
cmd = ["curl", "-s", "-w", "\n%{http_code}", "-X", "POST", f"{BASE}{path}",
"-H", "Content-Type: application/json", "-d", json.dumps(data)]
r = subprocess.run(cmd, capture_output=True, text=True, timeout=15)
parts = r.stdout.rsplit("\n", 1)
body = parts[0] if len(parts) > 1 else r.stdout
code = int(parts[1]) if len(parts) > 1 else 0
return code, body
# TC1: GET /agents returns 200 + HTML contains "Agents" title + profile table
code, html = curl("/agents")
if code == 200 and "Agents" in html and "profile" in html.lower():
passed += 1
print(f" PASS GET /agents: HTTP {code}, has title + profile refs")
else:
failed += 1
print(f" FAIL GET /agents: HTTP {code}, title={('Agents' in html)}, profile={('profile' in html.lower())}")
# TC2: /agents HTML has create button + delete confirm + chat modal
code, html = curl("/agents")
has_create = "create" in html.lower() or "新建" in html or "创建" in html
has_confirm = "confirm" in html.lower()
has_chat = "chat" in html.lower() or "消息" in html or "发消息" in html
if has_create and has_confirm and has_chat:
passed += 1
print(f" PASS /agents HTML: create={has_create} confirm={has_confirm} chat={has_chat}")
else:
failed += 1
print(f" FAIL /agents HTML: create={has_create} confirm={has_confirm} chat={has_chat}")
# TC3: /agents HTML has no Jinja2 escaped quotes or backslash bugs
code, html = curl("/agents")
ok = True
msgs = []
if 'style=\\' in html:
ok = False; msgs.append("STYLE BACKSLASH BUG")
if 'data-action=\\"' in html:
ok = False; msgs.append("JINJA2 ESCAPED QUOTES")
if ok:
passed += 1
print(f" PASS /agents HTML: no escape bugs")
else:
failed += 1
print(f" FAIL /agents HTML: {'; '.join(msgs)}")
# TC4: /agents HTML has default profile marker (◆ or similar)
code, html = curl("/agents")
if "default" in html:
passed += 1
print(f" PASS /agents HTML: contains 'default' profile ref")
else:
failed += 1
print(f" FAIL /agents HTML: no 'default' profile ref found")
# TC5: GET /agent/default returns 200 + SOUL.md content + skills list
code, html = curl("/agent/default")
if code == 200 and ("skill" in html.lower() or "SOUL" in html or "soul" in html.lower()):
passed += 1
print(f" PASS GET /agent/default: HTTP {code}, has skill/soul refs")
else:
failed += 1
print(f" FAIL GET /agent/default: HTTP {code}, soul={('soul' in html.lower())}, skill={('skill' in html.lower())}")
# TC6: /agent/default HTML has no escape bugs
code, html = curl("/agent/default")
ok = True
msgs = []
if 'style=\\' in html:
ok = False; msgs.append("STYLE BACKSLASH BUG")
if 'data-action=\\"' in html:
ok = False; msgs.append("JINJA2 ESCAPED QUOTES")
if ok:
passed += 1
print(f" PASS /agent/default HTML: no escape bugs")
else:
failed += 1
print(f" FAIL /agent/default HTML: {'; '.join(msgs)}")
print(f"\n{passed}/{passed+failed} 通过")
sys.exit(0 if failed == 0 else 1)