front: автоматическая генерация скриншотов скриптом

This commit is contained in:
2025-12-01 16:17:59 +03:00
parent 3bc726535e
commit 92120362a3
22 changed files with 255 additions and 4 deletions

View File

@@ -0,0 +1,148 @@
import subprocess
import pathlib
import time
import socket
import os
import json
from selenium import webdriver
from selenium.webdriver.common.by import By
BASE = pathlib.Path(__file__).parent
CONFIG_DIR = BASE / "config"
MODEM_TYPES = {}
for _fname in os.listdir(CONFIG_DIR):
if not _fname.endswith(".json"):
continue
path = os.path.join(CONFIG_DIR, _fname)
try:
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
except Exception as e:
print(f"[WARN] Failed to read {path}: {e}")
continue
modem_type = data.get("modem_type")
if modem_type is None:
print(f"[WARN] {_fname} ignored: no 'modem_type' field")
continue
MODEM_TYPES[modem_type] = data
BASE_URL = "http://localhost:8080/"
SCREEN_WIDTH = 1200
LOGIN = {
"username": "admin",
"password": "admin",
}
def wait_port(port=8080, host="127.0.0.1"):
for _ in range(100):
try:
socket.create_connection((host, port), timeout=1)
return True
except:
time.sleep(0.1)
raise RuntimeError("TCP port 8080 did not open in time")
def run_server(modem, build):
binary = BASE / f"../cmake-build-{build}-{modem}/terminal-web-server"
proc = subprocess.Popen([
binary,
"nossl",
"0.0.0.0",
"8080",
"../static"
])
return proc
def create_driver():
opts = webdriver.FirefoxOptions()
serv = webdriver.FirefoxService(executable_path='/snap/bin/geckodriver')
driver = webdriver.Firefox(options=opts, service=serv)
driver.set_window_size(SCREEN_WIDTH, 1000)
driver.set_page_load_timeout(15)
return driver
def login(driver):
driver.get("http://localhost:8080/#")
# Проверяем, редиректнуло ли на /login
if "/login" in driver.current_url:
# Ищем поля
user = driver.find_element(By.NAME, "username")
pwd = driver.find_element(By.NAME, "password")
user.clear()
pwd.clear()
user.send_keys(LOGIN["username"])
pwd.send_keys(LOGIN["password"])
# submit
btn = driver.find_element(By.ID, "submit")
btn.click()
time.sleep(1)
# Проверка успешного входа
if "/login" in driver.current_url:
raise RuntimeError("Login failed: still on /login after submit")
def make_screenshots_or_checks(modem):
out_dir = BASE / "out" / modem
out_dir.mkdir(parents=True, exist_ok=True)
driver = create_driver()
try:
driver.get("http://localhost:8080/login")
driver.save_screenshot(str(out_dir / f"login.png"))
login(driver)
time.sleep(2)
for tab in MODEM_TYPES[modem]["tabs"]:
tab_name = tab["name"]
driver.find_element(By.CSS_SELECTOR, f'a[href="#{tab_name}"]').click()
# Проверка, что body загрузилось
time.sleep(1)
page_height = driver.execute_script("return document.body.scrollHeight")
driver.set_window_size(SCREEN_WIDTH, page_height + 200)
time.sleep(1)
driver.find_element(By.TAG_NAME, "body") # гарантирует что DOM есть
driver.save_screenshot(str(out_dir / f"{tab_name}.png"))
finally:
driver.quit()
def main():
for mt in MODEM_TYPES:
build = "debug"
print(f"\n=== {mt} ({build}) ===")
proc = run_server(mt, build)
try:
wait_port()
make_screenshots_or_checks(mt)
finally:
proc.terminate()
proc.wait()
print("Done.")
print("\nAll configurations processed.")
if __name__ == "__main__":
main()