abuse: полный пересчёт индекса только по явному вызову (env не тормозит scan)
Some checks failed
ci / test (3.10) (push) Has been cancelled
ci / test (3.11) (push) Has been cancelled
ci / test (3.12) (push) Has been cancelled

This commit is contained in:
Vlad Gothbreach
2026-10-27 01:21:01 +03:00
parent d0b2187319
commit 42a864419b
12 changed files with 1844 additions and 983 deletions

96
tools/ui_smoke.py Normal file
View File

@@ -0,0 +1,96 @@
"""Смоук панели в реальном Chromium: скриншоты + ошибки консоли.
python tools/ui_smoke.py [--url http://127.0.0.1:8078/] [--shots data/shots]
"""
import argparse
import asyncio
import json
import pathlib
import sys
from playwright.async_api import async_playwright
async def run(url, out):
out.mkdir(parents=True, exist_ok=True)
errors, report = [], {}
async with async_playwright() as p:
b = await p.chromium.launch()
pg = await b.new_page(viewport={"width": 1500, "height": 950})
pg.on("console", lambda m: errors.append([m.type, m.text]) if m.type in ("error",) else None)
pg.on("pageerror", lambda e: errors.append(["pageerror", str(e)]))
await pg.goto(url, wait_until="domcontentloaded", timeout=30000)
await pg.wait_for_selector(".kpi", timeout=20000)
await pg.wait_for_timeout(1200)
report["title"] = await pg.title()
report["nav"] = await pg.locator(".nav-i").count()
report["kpi"] = (await pg.locator(".kpi").all_inner_texts())[:4]
await pg.screenshot(path=str(out / "v2_overview.png"), full_page=False)
await pg.click("[data-nav=feed]")
await pg.wait_for_selector("#list .item", timeout=20000)
report["feed_rows"] = await pg.locator(".item").count()
await pg.screenshot(path=str(out / "v2_feed.png"))
await pg.locator(".item").first.click()
await pg.wait_for_timeout(1200)
report["drawer"] = (await pg.locator("#d-title").inner_text())[:100]
await pg.screenshot(path=str(out / "v2_drawer.png"))
await pg.keyboard.press("Escape")
await pg.click("[data-nav=sources]")
await pg.wait_for_timeout(1500)
report["src_rows"] = await pg.locator("#src-tbl tbody tr").count()
await pg.screenshot(path=str(out / "v2_sources.png"))
await pg.click("[data-nav=abuse]")
await pg.wait_for_timeout(1500)
report["abuse_rows"] = await pg.locator(".item").count()
await pg.screenshot(path=str(out / "v2_abuse.png"))
await pg.click("[data-nav=runs]")
await pg.wait_for_timeout(900)
report["run_rows"] = await pg.locator("#r-tbl tbody tr").count()
await pg.screenshot(path=str(out / "v2_runs.png"))
await pg.click("[data-nav=tg]")
await pg.wait_for_timeout(2000)
report["tg"] = (await pg.locator(".card").first.inner_text())[:160].replace("\n", " | ")
await pg.screenshot(path=str(out / "v2_tg.png"))
await pg.click("[data-nav=keys]")
await pg.wait_for_timeout(800)
report["key_rows"] = await pg.locator("#k-tbl tbody tr").count()
await pg.screenshot(path=str(out / "v2_keys.png"))
await pg.click("[data-nav=digest]")
await pg.wait_for_timeout(500)
await pg.click("[data-act=digest]")
await pg.wait_for_timeout(6000)
report["digest_chars"] = len(await pg.locator("#d-out").inner_text())
await pg.screenshot(path=str(out / "v2_digest.png"))
await pg.click("[data-nav=watch]")
await pg.wait_for_timeout(600)
await pg.screenshot(path=str(out / "v2_watch.png"))
# мобильный вид
await pg.set_viewport_size({"width": 420, "height": 900})
await pg.click("[data-nav=feed]")
await pg.wait_for_timeout(1200)
await pg.screenshot(path=str(out / "v2_mobile.png"))
await b.close()
report["console"] = errors[:12]
print(json.dumps(report, ensure_ascii=False, indent=1))
return 0 if not errors else 1
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--url", default="http://127.0.0.1:8078/")
ap.add_argument("--shots", default="data/shots")
a = ap.parse_args()
sys.exit(asyncio.run(run(a.url, pathlib.Path(a.shots))))
if __name__ == "__main__":
main()