fix(M02): 상세 머리 [돌아가기] = 일반 단추 · 머리 단추 대비 시나리오(43-5 · E1)
- 도면 · 일위대가 · 면적산출 상세 [돌아가기] = 공용 기본(filled · 32px · 머리 단추와 같은 높이 · ghost sm 아님) - E1 대비 1.11 = ORCA 탭에서 단추 color 전환이 멈춘 채 읽힌 착오 · 전환 끄고 재면 어두움 8.01 · 밝음 16.65 → 색 고침 없음 - 시나리오 resources/tester/ui_checks/43-5_돌아가기_대비.js · 시험 한 줄 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVPp2o6Mh2FZJr72yW3ofZ
This commit is contained in:
@@ -130,8 +130,8 @@ export function createMain(
|
||||
const title = el("h2", { className: "m02-main__title", text: L("M02_PickTemplate") });
|
||||
const reload = createButton({ label: L("M02_Reload"), variant: "ghost" });
|
||||
const save = createButton({ label: L("M02_Save"), variant: "filled" });
|
||||
// 구조물 도면 · 면적산출 상세 화면 → 구조물집계표(그 열 고른 채)
|
||||
const back = createButton({ label: L("M02_Back"), variant: "ghost", size: "sm" });
|
||||
// 구조물 도면 · 일위대가 · 면적산출 상세 화면 → 구조물집계표(그 열 고른 채) · 일반 단추(43-5 · 알약 · ghost 아님)
|
||||
const back = createButton({ label: L("M02_Back") });
|
||||
const slot = el("div", { className: "m02-main__slot" }); // 도면 양식의 작도 영역 칸이 들어옴
|
||||
const notice = el("div", { className: "m02-main__notice", attrs: { hidden: "" } });
|
||||
const host = el("div", { className: "m02-main__host" });
|
||||
|
||||
@@ -238,3 +238,10 @@ def test_상세_화면_돌아가기는_집계표로_그_열_고른_채():
|
||||
body = main.split('back.addEventListener("click"')[1]
|
||||
assert "confirmLeave()" in body and "STRUCTURE_TABLE" in body
|
||||
assert "sheet?.selectColumn(column)" in body
|
||||
|
||||
|
||||
def test_상세_머리_돌아가기는_일반_단추():
|
||||
"""43-5 — 도면 · 일위대가 · 면적산출 상세 머리 [돌아가기] = 공용 기본 단추(filled · 같은 높이 ·
|
||||
알약 · ghost · sm 아님) · 대비는 ui_checks/43-5 시나리오(어두움 8.01)."""
|
||||
main = _text(MAIN)
|
||||
assert 'const back = createButton({ label: L("M02_Back") });' in main
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/* 43-5 · E1 — 도면 · 일위대가 · 면적산출 상세 머리 [돌아가기] 꼴 · 머리 단추 글자 대비(밝음 · 어두움)
|
||||
* 시작 화면: M02 마스터 템플릿 · 마스터 층(#/m02-master-template?open=구조물조합&root=master) · 시스템 관리자
|
||||
* 부르는 법: orca eval --expression "$(cat 이 파일)" (async 식 · JSON 글을 돌려줌)
|
||||
* 기대 수치:
|
||||
* - 세 상세 모두 back.cls = "ui-btn ui-btn--filled"(ghost · sm 없음) · back.h = 머리 다른 단추 높이(±1px)
|
||||
* - 밝음 · 어두움(앱 ☾ 단추) 모두 머리 보이는 단추 대비 ≥ 4.5
|
||||
* - 끝나면 처음 테마로 되돌림(theme.end = theme.start)
|
||||
* ⚠ 단추 color 전환(120ms)이 ORCA 탭에선 0ms 에 멈춰 옛 색이 읽힘(1.11 착오 · E1) — 재는 동안 전환을 끔
|
||||
*/
|
||||
(async () => {
|
||||
const w = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
const rgb = (s) => (s.match(/[\d.]+/g) || []).map(Number);
|
||||
const lum = ([r, g, b]) => {
|
||||
const f = (v) => ((v /= 255) <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4);
|
||||
return 0.2126 * f(r) + 0.7152 * f(g) + 0.0722 * f(b);
|
||||
};
|
||||
/** 실제로 보이는 바탕 — 투명이면 조상으로 */
|
||||
const bgOf = (el) => {
|
||||
for (let e = el; e; e = e.parentElement) {
|
||||
const c = rgb(getComputedStyle(e).backgroundColor);
|
||||
if (c.length >= 3 && (c.length < 4 || c[3] > 0.5)) return c.slice(0, 3);
|
||||
}
|
||||
return [255, 255, 255];
|
||||
};
|
||||
const ratio = (el) => {
|
||||
const a = lum(rgb(getComputedStyle(el).color).slice(0, 3));
|
||||
const b = lum(bgOf(el));
|
||||
return +((Math.max(a, b) + 0.05) / (Math.min(a, b) + 0.05)).toFixed(2);
|
||||
};
|
||||
const theme = () => document.documentElement.getAttribute("data-theme") || "auto";
|
||||
const moon = () =>
|
||||
[...document.querySelectorAll("button")].find((b) => /^[☾☀]$/.test(b.textContent.trim()));
|
||||
const headButtons = () =>
|
||||
[...document.querySelectorAll(".m02-main__head button")].filter(
|
||||
(b) => !b.hidden && b.offsetParent,
|
||||
);
|
||||
const openRow = async (sectionTitle, prefix) => {
|
||||
const sec = [...document.querySelectorAll(".m02-side__summary > section")].find(
|
||||
(s) => s.querySelector("h3").textContent.trim() === sectionTitle,
|
||||
);
|
||||
sec.classList.remove("is-collapsed");
|
||||
[...sec.querySelectorAll("button")].find((b) => b.textContent.startsWith(prefix)).click();
|
||||
await w(5000);
|
||||
};
|
||||
const measure = () => {
|
||||
const back = [...document.querySelectorAll(".m02-main__head button")].find(
|
||||
(b) => b.textContent.trim() === "돌아가기",
|
||||
);
|
||||
const others = headButtons().filter((b) => b !== back);
|
||||
return {
|
||||
title: document.querySelector(".m02-main__title")?.textContent,
|
||||
back: back && {
|
||||
cls: back.className,
|
||||
h: Math.round(back.getBoundingClientRect().height),
|
||||
radius: getComputedStyle(back).borderRadius,
|
||||
},
|
||||
otherH: others.map((b) => Math.round(b.getBoundingClientRect().height)),
|
||||
contrast: Object.fromEntries(
|
||||
headButtons().map((b) => [b.textContent.trim() || b.title, ratio(b)]),
|
||||
),
|
||||
};
|
||||
};
|
||||
const still = document.createElement("style");
|
||||
still.textContent = "*,*::before,*::after{transition:none!important}";
|
||||
document.head.append(still);
|
||||
const start = theme();
|
||||
const out = { theme: { start }, pages: {} };
|
||||
for (const [name, sec, prefix] of [
|
||||
["도면", "구조물 도면", "SD-000001"],
|
||||
["일위대가", "일위대가", "SU-000001"],
|
||||
["면적산출", "면적산출", "SA-000001"],
|
||||
]) {
|
||||
await openRow(sec, prefix);
|
||||
const light = measure();
|
||||
moon()?.click();
|
||||
await w(400);
|
||||
const dark = { theme: theme(), ...measure() };
|
||||
moon()?.click();
|
||||
await w(400);
|
||||
out.pages[name] = { light, dark };
|
||||
}
|
||||
if (theme() !== start) moon()?.click();
|
||||
out.theme.end = theme();
|
||||
still.remove();
|
||||
const all = Object.values(out.pages).flatMap((p) => [
|
||||
...Object.values(p.light.contrast),
|
||||
...Object.values(p.dark.contrast),
|
||||
]);
|
||||
out.minContrast = Math.min(...all);
|
||||
out.backOk = Object.values(out.pages).every(
|
||||
(p) =>
|
||||
p.light.back?.cls === "ui-btn ui-btn--filled" &&
|
||||
p.light.otherH.every((h) => Math.abs(h - p.light.back.h) <= 1),
|
||||
);
|
||||
return JSON.stringify(out);
|
||||
})();
|
||||
Reference in New Issue
Block a user