#!/usr/bin/env python3 """CDP 前端验证:截图 + 控制台检查 + 页面状态""" import json, time, base64, urllib.request, os # Step 1: 导航到前端页面 (PUT /json/new) print("=== CDP 前端验证 ===") print("Navigating to page...") req = urllib.request.Request("http://127.0.0.1:9225/json/new?url=http://localhost:5199/", method="PUT") try: resp = urllib.request.urlopen(req, timeout=10) page_data = json.loads(resp.read()) page_id = page_data.get("id","") ws_url = page_data.get("webSocketDebuggerUrl","") print(f" Page: id={page_id} title={page_data.get('title','')[:80]}") print(f" WS_URL: {ws_url[:80]}") except Exception as e: print(f" Navigation failed: {e}") import sys; sys.exit(1) # Step 2: 连接到页面 WebSocket from websocket import create_connection ws = create_connection(ws_url, timeout=10) print(" Connected to page WebSocket") def cdp(method, params=None, msg_id=1): payload = json.dumps({"id": msg_id, "method": method, "params": params or {}}) ws.send(payload) def recv_msgs(timeout=3): ws.settimeout(timeout) msgs = [] try: while True: msgs.append(ws.recv()) except: pass return msgs def find_result(msgs, msg_id): for m in msgs: try: d = json.loads(m) if d.get("id") == msg_id: return d.get("result",{}) except: pass return None # Step 3: 启用 domains print("\nEnabling domains...") cdp("Runtime.enable", {}, 1) cdp("Page.enable", {}, 2) cdp("Log.enable", {}, 3) recv_msgs(2) print(" Domains enabled") # Step 4: 等待页面完全加载后截图 print("\nWaiting for page to load...") time.sleep(3) cdp("Page.captureScreenshot", {"format": "png"}, 10) msgs = recv_msgs(5) r = find_result(msgs, 10) if r and r.get("data"): img = base64.b64decode(r["data"]) with open("/tmp/cyrene_screenshot_round12.png", "wb") as f: f.write(img) print(f" Screenshot saved: {len(img)} bytes") else: print(f" Screenshot failed: {str(r)[:200]}") # Step 5: 获取控制台日志 print("\nConsole messages (Log.entryAdded):") ws.settimeout(2) logs = [] for i in range(15): try: data = ws.recv() d = json.loads(data) if d.get("method") == "Log.entryAdded": entry = d["params"]["entry"] level = entry.get("level","log") text = entry.get("text","") url = entry.get("url","") logs.append(f" [{level}] {text[:200]} ({url})") elif d.get("method") == "Runtime.exceptionThrown": exc = d["params"].get("exceptionDetails",{}) logs.append(f" [EXCEPTION] {exc.get('text','')}") except: break if logs: for l in logs: print(l) else: print(" (none)") # Step 6: 页面状态检查 print("\nPage state:") checks = [ ("title", "document.title"), ("readyState", "document.readyState"), ("root exists?", "document.getElementById('root') ? 'yes' : 'no'"), ("body children", "document.body ? document.body.children.length : -1"), ("login form?", "document.querySelector('form') ? 'yes' : 'no'"), ("all text content (first 300)", "document.body ? (document.body.innerText || '').substring(0, 300) : 'no body'"), ] for idx, (label, expr) in enumerate(checks): cdp("Runtime.evaluate", {"expression": expr, "returnByValue": True}, 100 + idx) msgs = recv_msgs(2) r = find_result(msgs, 100 + idx) val = r.get("result",{}).get("value","?") if r else "?" print(f" {label}: {val}") # Step 7: 前端 JS 错误检测 print("\nJS Errors (Runtime.exceptionThrown):") ws.settimeout(1) errors = [] for i in range(5): try: d = json.loads(ws.recv()) if d.get("method") == "Runtime.exceptionThrown": exc = d["params"]["exceptionDetails"] errors.append(f" {exc.get('text','')} at {exc.get('url','')}:{exc.get('lineNumber','')}") except: break if errors: for e in errors: print(e) else: print(" No JS exceptions detected") ws.close() print("\n[DONE]")