# -*- coding: utf-8 -*- """探针:复刻 demo_smoke 步骤12 换组路径,dump #fiOut / toast / 网络轨迹""" import pathlib, sys, io, time, json, urllib.request, urllib.parse sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') from playwright.sync_api import sync_playwright ROOT = pathlib.Path(__file__).resolve().parent DEMO = ROOT / "demo" / "index.html" API = "http://localhost:8080" ADMIN = "739564171091247104" TS = time.strftime("%H%M%S") def post(url, data=None, token=None): body = urllib.parse.urlencode(data or {}).encode() req = urllib.request.Request(url, data=body, method="POST") req.add_header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8") if token: req.add_header("Authorization", "Bearer " + token) with urllib.request.urlopen(req, timeout=20) as r: return json.loads(r.read().decode()) tok = json.loads(urllib.request.urlopen(f"{API}/api/auth/debug/token?userId={ADMIN}", timeout=10).read().decode())["data"] # API 直建组A/组B/项2 ga = post(f"{API}/api/dict/group/saveOrUpdate", {"name": "e2d-探针组A-" + TS, "code": "e2d_pa_" + TS, "sortNo": 999}, tok) gb = post(f"{API}/api/dict/group/saveOrUpdate", {"name": "e2d-探针组B-" + TS, "code": "e2d_pb_" + TS, "sortNo": 999}, tok) def find_group(code): d = post(f"{API}/api/dict/group/page", {"current": 1, "size": 20, "keyword": code}, tok) return next((x for x in (d.get("data") or {}).get("content", []) if x.get("code") == code), None) ga_row, gb_row = find_group("e2d_pa_" + TS), find_group("e2d_pb_" + TS) print("组A:", ga_row and ga_row["id"], "组B:", gb_row and gb_row["id"]) post(f"{API}/api/dict/item/saveOrUpdate", {"groupId": str(ga_row["id"]), "name": "e2d-探针项2", "value": "e2d-v2-" + TS, "code": "e2d_pi2_" + TS, "sortNo": 999, "status": 1}, tok) ip = post(f"{API}/api/dict/item/page", {"current": 1, "size": 20, "groupId": str(ga_row["id"]), "keyword": "e2d_pi2_" + TS}, tok) item2 = next((x for x in (ip.get("data") or {}).get("content", []) if x["code"] == "e2d_pi2_" + TS), None) print("项2:", item2 and item2["id"]) with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page() page.set_default_timeout(15000) page.on("dialog", lambda d: (print(" [dialog]", d.type, d.message[:60]), d.accept())) reqs = [] def on_resp(r): if "/api/dict/item" in r.url: try: body = r.text()[:160] except Exception: body = "" reqs.append((r.request.method, r.request.post_data, r.url[-60:], r.status, body)) page.on("response", on_resp) page.goto(DEMO.as_uri() + "?api=" + API) page.wait_for_load_state("networkidle") page.click("button:has-text('uid 登录')") page.wait_for_selector(".toast-item:has-text('登录成功')", timeout=15000) page.wait_for_selector("#gBody tr td", timeout=15000) page.click("nav.tabs button[data-tab='item']") page.wait_for_timeout(600) page.select_option("#iGroup", str(ga_row["id"])) page.wait_for_timeout(600) page.click("#iBody tr:has-text('e2d-探针项2') td.ops button:has-text('编辑')") page.wait_for_selector("#fiGroup") page.select_option("#fiGroup", str(gb_row["id"])) page.click(".dfoot button.ok") page.wait_for_timeout(2500) print("toasts:", page.locator(".toast-item").all_text_contents()) print("fiOut:", page.inner_html("#fiOut")[:200]) print("== item 网络轨迹:") for r in reqs[-5:]: print(" ", r[0], "|", r[1], "|", r[2], "|", r[3], "|", r[4]) browser.close() # 清理 for g in (ga_row, gb_row): ip = post(f"{API}/api/dict/item/page", {"current": 1, "size": 50, "groupId": str(g["id"])}, tok) for it in (ip.get("data") or {}).get("content", []): try: post(f"{API}/api/dict/item/delete", {"id": str(it["id"])}, tok) except Exception as ex: print("item del fail", ex) try: post(f"{API}/api/dict/group/delete", {"id": str(g["id"])}, tok) except Exception as ex: print("group del fail", g["code"], ex) print("cleaned")