arm-ka-docs/scripts/mockup_crawl.py

89 lines
7.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import asyncio, json, os, re
from playwright.async_api import async_playwright
"""Съёмка экранов React-макета dkb_24.09.26 headless-браузером → PNG + report.json.
python scripts/mockup_crawl.py docs/mockup/dkb_24.09.26/dkb_24.09.26.html docs/mockup/screens
Зависимости: pip install playwright && playwright install chromium
"""
import sys
URL = "file://" + os.path.abspath(sys.argv[1])
OUT = sys.argv[2]
REPORT = {}
SLUG = {'Шахматка':'chess','Таблица корректировки':'corrections','Гудвилл':'goodwill','КФО':'kfo','КФО Общий':'kfo-total','Подтверждение КФО клиента':'kfo-client','Показать ЮЛ без ИНН':'osv-no-inn','Указать':'osv-map-counterparty','ЮЛ':'le','ГСК':'gsk','ГСЗ':'gsz','История':'history','Архив':'archive'}
async def click_text(pg, text, tag=None, nth=0, exact=False):
ok = await pg.evaluate("""([text, tag, nth, exact]) => {
const els=[...document.querySelectorAll(tag || 'button, a, [role=tab], [role=menuitem], tr, li, div')]
.filter(e => { const t=(e.innerText||'').trim().replace(/\\s+/g,' '); return (exact ? t===text : t.startsWith(text)) && e.getBoundingClientRect().width>5; });
const e = els[nth]; if(!e) return false; e.scrollIntoView({block:'center'}); e.click(); return true; }""", [text, tag, nth, exact])
await pg.wait_for_timeout(600); return ok
async def snap(pg, name, note=""):
await pg.screenshot(path=f"{OUT}/{name}.png")
d = await pg.evaluate("""() => { const q=s=>[...document.querySelectorAll(s)]; const t=e=>(e.innerText||'').trim().replace(/\\s+/g,' ');
const modal = q('[class*=modal],[class*=Modal],[role=dialog],[class*=drawer],[class*=Drawer],[class*=overlay]').filter(e=>e.getBoundingClientRect().width>100).map(t).slice(0,1).map(x=>x.slice(0,600));
return {heads:q('h1,h2,h3').map(t).filter(Boolean).slice(0,10), buttons:[...new Set(q('button').map(t).filter(x=>x&&x.length<50))],
cols:[...new Set(q('th').map(t).filter(Boolean))].slice(0,40), crumbs:q('[class*=crumb],[class*=Crumb]').map(t).slice(0,1),
modal, labels:[...new Set(q('label, [class*=label], [class*=Label]').map(t).filter(x=>x&&x.length<40))].slice(0,30),
body:t(document.body).slice(0,3000)} }""")
d["note"]=note; REPORT[name]=d
print(f"## {name} {d['crumbs']} {d['heads'][:3]} | cols={d['cols'][:16]} | modal={bool(d['modal'])}")
return d
SIDEBAR = {'Новая консолидация','Группы компаний','Монозаемщики','ГК и организации','ЮЛ вне ГК','Единое хранилище','Журнал действий'}
async def fresh(pg):
await pg.goto(URL); await pg.evaluate("() => { localStorage.clear(); sessionStorage.clear(); }"); await pg.goto(URL); await pg.wait_for_timeout(1600)
async def goto_report(pg):
await fresh(pg)
await click_text(pg, "Группы компаний", "button"); await click_text(pg, "Консолидации", "button"); await click_text(pg, "К отчетности", "button")
async def main():
async with async_playwright() as p:
b = await p.chromium.launch(); pg = await b.new_page(viewport={"width":1600,"height":1000})
# --- карточка отчёта и вкладки
await goto_report(pg); d = await snap(pg, "30-report-osv", "вкладка ОСВ по умолчанию")
for i, t in enumerate(["Шахматка","Таблица корректировки","Гудвилл","КФО","КФО Общий","Подтверждение КФО клиента"]):
if await click_text(pg, t, "button", 0, True):
if i == 0: await snap(pg, "31-00-inn-warning", "модалка «Остались неуказанные ИНН» при уходе с ОСВ")
await click_text(pg, "Перейти", "button", 0, True)
await snap(pg, f"31-{i+1:02d}-{SLUG[t]}", f"вкладка {t}")
# сводная ОСВ: доп. кнопки
await click_text(pg, "ОСВ", "button", 0, True)
for t in ["Показать ЮЛ без ИНН", "Указать"]:
if await click_text(pg, t, "button"): await snap(pg, f"32-{SLUG[t]}", f"ОСВ → {t}"); await goto_report(pg)
# изменить статус
if await click_text(pg, "Изменить статус", "button"): await snap(pg, "33-change-status", "модалка смены статуса")
# --- список консолидаций: взять в работу, документы организации, состав, чек-лист
await fresh(pg)
await click_text(pg, "Группы компаний", "button"); await click_text(pg, "Консолидации", "button")
await snap(pg, "34-consolidations", "список консолидаций ГК + организации")
for t, n in [("Взять в работу","35-take-in-work"),("Редактировать состав","36-edit-members"),("Скачать чек-лист","37-checklist"),("Импорт","38-import")]:
if await click_text(pg, t, "button"): await snap(pg, n, t); await pg.keyboard.press("Escape"); await click_text(pg,"Отмена","button"); await click_text(pg,"Закрыть","button")
if await click_text(pg, "Документы", "button"):
await snap(pg, "39-org-documents", "панель первичных документов организации")
for t, n in [("Загрузить документы","40-upload"),("Загрузить","40-upload")]:
if await click_text(pg, t, "button"): await snap(pg, n, t); await pg.keyboard.press("Escape"); await click_text(pg,"Отмена","button"); break
# открыть документ (строка таблицы в панели)
if await click_text(pg, "", "[class*=drawer] tr, [class*=Drawer] tr, [class*=panel] tr, [class*=Panel] tr", 1):
await snap(pg, "41-document-view", "просмотр/проверка распознавания документа")
# --- новая консолидация
await fresh(pg)
await click_text(pg, "Новая консолидация", "button"); await snap(pg, "42-new-consolidation", "модалка создания консолидации")
# --- справочник ГК: карточка ГК (стартовый экран)
await fresh(pg)
await snap(pg, "50-directory-gk", "справочник ГК и организации (стартовый экран)")
for t, n in [("Создать ГК/ЮЛ","51-create-gk"),("Импорт из файла","52-import-file")]:
if await click_text(pg, t, "button"): await snap(pg, n, t); await pg.keyboard.press("Escape"); await click_text(pg,"Отмена","button")
# правая панель: вкладки ЮЛ/ГСК/ГСЗ
for t in ["ЮЛ","ГСК","ГСЗ","История","Архив"]:
if await click_text(pg, t, "button", 0, True): await snap(pg, f"53-{SLUG[t]}", f"вкладка {t} в карточке ГК")
# кликнуть по ЮЛ в составе ГК
if await click_text(pg, "ООО", None, 0): await snap(pg, "54-legal-entity", "карточка ЮЛ")
# --- монозаёмщики, ЕХ, журнал, ЮЛ вне ГК (кратко)
for t, n in [("Монозаемщики","60-mono"),("ЮЛ вне ГК","61-le-outside"),("Единое хранилище","62-ex"),("Журнал действий","63-audit")]:
await fresh(pg); await click_text(pg, t, "button"); await snap(pg, n, t)
json.dump(REPORT, open(f"{OUT}/report.json","w"), ensure_ascii=False, indent=1)
await b.close()
asyncio.run(main())