test(511-C 화면 · 둘레): 검증_sub4 B05 유토 배분 판 server 대 both — server = /haul-plan 1 · 배분 모듈 안 받음 · both = /haul-plan 0 · 모듈 받음 · 유토곡선 그림 같음 · 계산 자리 창 E2 열림(기본 꺼짐) · 서버만 G3 D1 D2 N1 까닭 넷 다름(test_511_c_haul_browser) · 511-B1 판 열린 줄에 haul — 요구 320-4
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -94,6 +94,7 @@ def test_판_다섯_줄_잠금_기본값_그대로():
|
||||
"route", # B-5 = 엶(511-B B-5)
|
||||
"stations", # B-2 끝 = 엶(511-B B-2)
|
||||
"profile", # B-3 엶(511-B · test_511_b3_profile_node)
|
||||
"haul", # 511-C E2 엶(기본 server · 판 파일 바뀜 0)
|
||||
"fixed_browser",
|
||||
}
|
||||
committed = subprocess.run( # noqa: S603 — 고정 실행 파일
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
"""PLAN 511-C 화면 — 자기 포트 Playwright 머리 없는 브라우저 · 서버가 떠 있을 때만 · 검증_sub4.
|
||||
|
||||
- 판 haul 기본(server) = B05 계획고 ▲ 뒤 /haul-plan 요청 · 배분 모듈 안 받음(첫 묶음 밖)
|
||||
- 판 haul both = /haul-plan 0 · 배분 모듈을 그때 받아 셈 · 유토곡선(배분 balloon 포함) 그림
|
||||
= server 판과 같음
|
||||
- 계산 자리 창 = E2 열린 줄(기본 꺼짐) · 서버만 G3 D1 D2 N1 줄마다 다른 까닭
|
||||
- 저장 안 함(세션 초안만) · 판 = 파일 바이트 되돌림 · 시험 브라우저 표식 시스템 로그 행만 지움
|
||||
|
||||
./venv/Scripts/python.exe -m pytest resources/tester/test_511_c_haul_browser.py -q -s
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
ROOT = HERE.parents[1]
|
||||
if str(HERE) not in sys.path:
|
||||
sys.path.insert(0, str(HERE))
|
||||
|
||||
from helper_verify_project import own_ports # noqa: E402
|
||||
from test_511_a_calc_sites_browser import ( # noqa: E402, F401
|
||||
_UP,
|
||||
JS_GRADE, # noqa: E402
|
||||
_started,
|
||||
)
|
||||
|
||||
API, BASE = own_ports()
|
||||
BOARD = ROOT / "resources" / "master_template" / "calc_sites.json"
|
||||
PROJECT = "c725d747-50ae-46b0-87ce-4d4e56a53cf3" # 검증_sub4(OWNERS.md)
|
||||
MARK = "AisloTest-511-C"
|
||||
CARD = "계산 자리"
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
_UP is None or _UP != _started(API), reason="이 폴더 서버 없음 · vite 가 이 폴더 백엔드로 안 감"
|
||||
)
|
||||
|
||||
# 그림 글 — 그릴 때마다 새로 짓는 clipPath 이름만 한 글자로(값 아님)
|
||||
JS_CHART = r"""() => {
|
||||
const chart = document.querySelector('.b05-profile__masshaul-chart');
|
||||
return chart ? chart.innerHTML.replace(/mass-clip-[a-z0-9]+/g, 'mass-clip') : null;
|
||||
}"""
|
||||
JS_LOADED = r"""() => performance.getEntriesByType('resource').map((e) => e.name)
|
||||
.some((n) => /common_util_mass_haul_balance\.ts/.test(n))"""
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def ctx():
|
||||
sync = pytest.importorskip("playwright.sync_api")
|
||||
committed = BOARD.read_bytes()
|
||||
cred = json.loads((ROOT / "tmp" / "aislo_cred.json").read_text(encoding="utf-8"))
|
||||
try:
|
||||
with sync.sync_playwright() as play:
|
||||
chrome = play.chromium.launch(channel="msedge", headless=True)
|
||||
context = chrome.new_context(viewport={"width": 1600, "height": 1000}, user_agent=MARK)
|
||||
login = {k: cred[k] for k in ("email", "password")}
|
||||
r = context.request.post(f"{BASE}/api/auth/login/request", data=login, timeout=60000)
|
||||
assert r.ok, f"로그인 실패 {r.status}" # 비밀번호는 안 찍음
|
||||
try:
|
||||
yield context
|
||||
finally:
|
||||
chrome.close()
|
||||
finally:
|
||||
BOARD.write_bytes(committed)
|
||||
_drop_test_logs()
|
||||
|
||||
|
||||
def _drop_test_logs() -> None:
|
||||
from config.config_db import close_db_pool, init_db_pool
|
||||
|
||||
async def run():
|
||||
pool = await init_db_pool()
|
||||
try:
|
||||
async with pool.acquire() as connection, connection.cursor() as cursor:
|
||||
await cursor.execute("DELETE FROM system_audit_logs WHERE user_agent = %s", (MARK,))
|
||||
await connection.commit()
|
||||
finally:
|
||||
await close_db_pool()
|
||||
|
||||
asyncio.run(run())
|
||||
|
||||
|
||||
def _board(haul: str | None) -> None:
|
||||
board = json.loads(BOARD.read_text("utf-8"))
|
||||
board["sites"].pop("haul", None)
|
||||
if haul:
|
||||
board["sites"]["haul"] = haul
|
||||
BOARD.write_text(json.dumps(board, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
def _run(context) -> dict:
|
||||
page = context.new_page()
|
||||
page.add_init_script(
|
||||
f"localStorage.setItem('frd_current_project_id', '{PROJECT}');"
|
||||
" performance.setResourceTimingBufferSize(20000);"
|
||||
)
|
||||
posts: list[dict] = []
|
||||
|
||||
def on_response(res):
|
||||
if res.url.endswith("/haul-plan") and res.request.method == "POST":
|
||||
posts.append(res.json())
|
||||
|
||||
page.on("response", on_response)
|
||||
page.goto(f"{BASE}/#/b05-profile", wait_until="domcontentloaded")
|
||||
page.wait_for_function("() => !!window.__aisloPipeline", timeout=90000)
|
||||
page.wait_for_timeout(9000)
|
||||
page.click(".ui-workflow-overlay__handle--bottom") # 종단 펼침
|
||||
page.wait_for_timeout(2000)
|
||||
if page.evaluate(JS_CHART) is None:
|
||||
page.click(".b05-profile__masshaul-handle") # 유토곡선 펼침
|
||||
page.evaluate(JS_GRADE) # 계획고 ▲ 한 번(가운데 측점 +0.3 m) — 새 누가토량 → 배분 다시
|
||||
page.wait_for_timeout(5000)
|
||||
out = {"posts": posts, "chart": page.evaluate(JS_CHART), "loaded": page.evaluate(JS_LOADED)}
|
||||
page.close()
|
||||
return out
|
||||
|
||||
|
||||
def test_haul_server_both_그림_같음(ctx):
|
||||
_board(None) # 판 파일에 haul 없음 = 기본 server
|
||||
server = _run(ctx)
|
||||
_board("both")
|
||||
both = _run(ctx)
|
||||
_board(None)
|
||||
assert server["posts"] and all(p["haul_plan"] for p in server["posts"])
|
||||
assert any(p["haul_plan"]["transfers"] for p in server["posts"])
|
||||
assert not server["loaded"] # 기본값 = 배분 모듈 안 받음
|
||||
assert both["posts"] == [] and both["loaded"]
|
||||
assert server["chart"] and "balloon" in server["chart"]
|
||||
assert both["chart"] == server["chart"]
|
||||
print("posts", len(server["posts"]), "chart bytes", len(server["chart"]))
|
||||
|
||||
|
||||
def test_계산_자리_창_haul_엶_서버만_까닭(ctx):
|
||||
page = ctx.new_page()
|
||||
page.goto(f"{BASE}/#/b01-account", wait_until="domcontentloaded")
|
||||
page.wait_for_selector(".b01-dashboard__setting-card", timeout=60000)
|
||||
page.get_by_text(CARD, exact=True).click()
|
||||
page.wait_for_selector(".b01-dashboard__calc-sites", timeout=30000)
|
||||
rows = page.eval_on_selector_all(
|
||||
".b01-dashboard__calc-sites tbody tr",
|
||||
"(trs) => trs.map((tr) => ({ name: tr.cells[0].textContent.trim(),"
|
||||
" why: tr.cells[3].textContent.trim(),"
|
||||
" boxes: [...tr.querySelectorAll('input')].map((i) => [i.checked, i.disabled]) }))",
|
||||
)
|
||||
page.close()
|
||||
calcs = {row["name"].split(" · ")[0]: row for row in rows if " · " in row["name"]}
|
||||
assert calcs["E2"]["boxes"] == [[False, False], [True, True]] # 열림 · 기본 server(꺼짐)
|
||||
whys = {no: calcs[no]["why"] for no in ("G3", "D1", "D2", "N1")}
|
||||
for no, word in {"G3": "DB", "D1": "래스터", "D2": "D1", "N1": "지형"}.items():
|
||||
assert word in whys[no] and calcs[no]["boxes"][0] == [False, True], (no, whys[no])
|
||||
assert len(set(whys.values())) == 4
|
||||
print(whys)
|
||||
Reference in New Issue
Block a user