test_s2_agents_frontend.py 3.25 KB
#!/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)