From a503683b9bb0afe478922c465b73f4eb22e9ecd9 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Tue, 6 Oct 2026 23:22:20 +0900 Subject: [PATCH] =?UTF-8?q?test(structure):=2065=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20?= =?UTF-8?q?=E2=80=94=20=EC=84=B8=EC=9B=94=EA=B5=90=20=C2=B7=20=EB=B0=95?= =?UTF-8?q?=EC=8A=A4=20=C2=B7=20=EB=AC=BC=EB=84=98=EC=9D=B4=20=EC=A2=8C?= =?UTF-8?q?=EC=B8=A1=20=ED=8C=A8=EB=84=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 화면 확인(검증_sub5 · ORCA): - 세월교 1 = 관경 → 수량(련) → 폭 → 높이 · 유입 흙막이 = 찰 10 · 1.5 · 5 · 5 + 옵션 줄 · 유출 없음 = 램프 3→2 · 잇기 줄 없음 - 추가 흙막이 · 도수로 상자 · [저장] → 파일 inlet_revet_* · soil_add_1_* · chute_add_1 · 다시 열어 같음 · 램프 4 - B06 측벽 고름 = 유입 상자 강조 · 좌측 측벽 높이 · 좌우 · 상하 · 바닥판 줄 0 - 새 세월교 = 1000 · 련 2 · 폭 10 · 높이 0.04(유량 뒤 자동) · 배관 → 세월교 = 높이 0.08 · 새 물넘이 = 경사 3 · 폭 5 · 높이 0.01 - 세월교 → 박스 = 2.0×2.0 · 날개벽 · 유출 없음 = 램프 3→2 - 검증 파일 · 세션 캐시는 미리 뜬 사본으로 되돌림 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01BVPp2o6Mh2FZJr72yW3ofZ --- .../tester/ui_checks/65_세월교_박스_물넘이.js | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 resources/tester/ui_checks/65_세월교_박스_물넘이.js diff --git a/resources/tester/ui_checks/65_세월교_박스_물넘이.js b/resources/tester/ui_checks/65_세월교_박스_물넘이.js new file mode 100644 index 000000000..77fa22d7e --- /dev/null +++ b/resources/tester/ui_checks/65_세월교_박스_물넘이.js @@ -0,0 +1,93 @@ +/* 65 — B05 · B06 좌측 「구조물 배치」 세월교 · 박스암거 · 물넘이 포장(PLAN 65-1 ~ 65-5) + * 시작 화면: B05 종단설계(#/b05-profile) · 검증 프로젝트(검증_sub5) · 목록에 「세월교 1」 + * 부르는 법: orca eval --expression "window.__m65='단계'; $(cat 이 파일)" + * shape — 세월교 1 고름 → 상자 · 칸 · 램프 수 + * edit — 유입 흙막이(기본값 칸) · 유출 없음(램프 줄어듦) · 추가 흙막이 · 도수로 · [저장] + * verify — 다시 연 값 · 램프 수 + * newford — 새 세월교(관경 · 련 · 폭 · 높이 자동) · 새 물넘이(경사각 3 · 폭 · 높이) — 저장 안 함 + * 되돌림: 검증 프로젝트 파일을 미리 떠 둔 사본으로(스크립트 밖) + */ +(async () => { + const MODE = window.__m65 || "shape"; + const w = (ms) => new Promise((r) => setTimeout(r, ms)); + const until = async (fn, ms = 20000) => { + for (let t = 0; t < ms; t += 200) { + if (fn()) return true; + await w(200); + } + return false; + }; + const spec = () => + [...document.querySelectorAll(".b05-structure__spec")].find((n) => n.offsetParent !== null); + const box = (c, i = 0) => spec()?.querySelectorAll(`[data-spec-container="${c}"]`)[i]; + const ctl = (c, item, i = 0) => + box(c, i)?.querySelector(`[data-spec-item="${c}.${item}"]`)?.querySelector("select, input"); + const set = async (c, item, v, i = 0) => { + const el = ctl(c, item, i); + el.value = v; + el.dispatchEvent(new Event("change", { bubbles: true })); + await w(300); + }; + const rows = () => + [...document.querySelectorAll(".b05-route__irregular-list li")].filter((l) => l.offsetParent); + const row = (re) => rows().find((l) => re.test(l.textContent.trim())); + const lamps = (re) => row(re)?.querySelectorAll(".b05-route__lamps i").length ?? -1; + const pick = async (re) => { + await until(() => !!row(re)); + const li = row(re); + (li.querySelector("button") ?? li).click(); + await w(800); + await until(() => !!spec()); + await w(400); + }; + const shape = () => + [...spec().querySelectorAll("[data-spec-container]")].map((b) => ({ + c: b.dataset.specContainer, + legend: b.querySelector("legend")?.firstChild?.textContent, + items: [...b.querySelectorAll("[data-spec-item]")] + .filter((n) => !n.hidden) + .map((n) => [n.dataset.specItem, n.querySelector("select, input")?.value ?? ""]), + fields: [...b.querySelectorAll(".b05-route__field")] + .filter((n) => !n.hidden && n.offsetParent) + .map((n) => n.querySelector("span")?.textContent), + link: !!b.querySelector("[data-spec-link]"), + option: [...b.querySelectorAll(".b05-structure__half-pair button")].map( + (x) => `${x.textContent}${x.disabled ? "(끔)" : ""}`, + ), + })); + const out = { mode: MODE }; + const FORD = /세월교 1$/; + + if (MODE === "shape") { + await pick(FORD); + out.shape = shape(); + out.lamps = lamps(FORD); + } + if (MODE === "edit") { + await pick(FORD); + out.lampsBefore = lamps(FORD); + await set("inlet", "structure", "흙막이"); + out.inlet = shape().find((b) => b.c === "inlet"); + await set("outlet", "structure", "없음"); + await w(800); + out.outlet = shape().find((b) => b.c === "outlet"); + out.lampsAfterNone = lamps(FORD); + for (const c of ["soil_add", "chute_add"]) { + spec().querySelector(`[data-spec-add="${c}"]`)?.click(); + await w(400); + } + await set("chute_add", "structure", "도수로"); + await set("inlet", "length", "8"); + out.lampsAfterAdd = lamps(FORD); + out.edited = shape(); + document.querySelector('[data-dock-action="save"]').click(); + await w(500); + out.saved = await until(() => !document.querySelector(".ui-overlay.is-active"), 60000); + } + if (MODE === "verify") { + await pick(FORD); + out.reopened = shape(); + out.lamps = lamps(FORD); + } + return JSON.stringify(out); +})();