/* 스프레드시트 D 화면 시험 틀 입구 — 견본 통합문서를 띄우고 window.ss* 로 수치를 꺼냄(ORCA eval). * 번들: node helper_spreadsheet_d_bundle.cjs harness → tmp/spreadsheet_d/harness.js */ const { createSpreadsheet } = require("../../../A00_Common/spreadsheet/spreadsheet"); const sample = require("../../../A00_Common/spreadsheet/spreadsheet_sample.json"); const host = document.getElementById("host"); window.ssSelect = null; window.ssChanges = 0; window.ssSample = JSON.parse(JSON.stringify(sample)); window.ss = createSpreadsheet(host, JSON.parse(JSON.stringify(sample)), { onChange: () => window.ssChanges++, onSelect: (s) => (window.ssSelect = s), inspect: true, }); window.ssCreate = createSpreadsheet; /** 칸 입력 값(A1) */ window.ssCell = (a1, sheet = "s1") => window.ss.getDoc().시트.find((s) => s.id === sheet).칸[a1] ?? null; /* 한 번에 도는 시나리오 — 탭이 새로 읽혀도 끊기지 않게 페이지 안에서 합성 사건으로 조작하고 수치를 모음. * (믿음 입력 — 진짜 키 · 마우스 · 한글 — 은 ORCA keypress · type · mouse 로 따로 잼) */ window.ssScenario = () => { const ta = () => document.querySelector(".ss-input"); const at = (a1) => { const d = document.querySelector(`[data-a1="${a1}"]`).getBoundingClientRect(); return { clientX: d.left + d.width / 2, clientY: d.top + d.height / 2, bubbles: true, button: 0, }; }; const grid = () => document.querySelector(".ss-grid-host"); const click = (a1, extra = {}) => { grid().dispatchEvent(new MouseEvent("mousedown", { ...at(a1), ...extra })); window.dispatchEvent(new MouseEvent("mouseup", at(a1))); }; const dragTo = (from, to) => { grid().dispatchEvent(new MouseEvent("mousedown", from)); window.dispatchEvent(new MouseEvent("mousemove", to)); window.dispatchEvent(new MouseEvent("mouseup", to)); }; const key = (k, o = {}) => document.activeElement.dispatchEvent( new KeyboardEvent("keydown", { key: k, bubbles: true, cancelable: true, ...o }), ); const type = (text) => { const t = document.activeElement; t.setRangeText(text, t.selectionStart, t.selectionEnd, "end"); t.dispatchEvent(new Event("input", { bubbles: true })); }; const shown = (a1) => document.querySelector(`[data-a1="${a1}"]`).textContent; const sel = () => `${ssSelect.칸}|${ssSelect.범위}`; const out = {}; // 한글 첫 글자 — compositionstart 로 편집 시작 · 같은 textarea 그대로 click("L2"); ta().dispatchEvent(new CompositionEvent("compositionstart", { data: "" })); out.imeEditing = document.querySelector(".ss").classList.contains("ss--editing") && document.activeElement === ta(); type("한"); key("Enter"); out.ime = [ssCell("L2"), sel()]; // 수 · 식 · 참조 가리키기(방향키 + 누르기) · 재계산 click("L3"); type("2"); key("Enter"); type("="); key("ArrowUp"); out.pointKey = ta().value; type("*"); click("J5"); out.pointClick = [ ta().value, [...document.querySelectorAll(".fg-ref")].map((x) => x.dataset.ref), ]; key("Enter"); out.calc = [ssCell("L4"), shown("L4")]; click("L3"); type("5"); key("Enter"); out.recalc = shown("L4"); // 되돌리기 · 다시 key("z", { ctrlKey: true }); out.undo = [ssCell("L3"), shown("L4")]; key("y", { ctrlKey: true }); out.redo = [ssCell("L3"), shown("L4")]; // Delete(서식 남김) · 되돌림 click("B4"); key("Delete"); out.del = ssCell("B4"); key("z", { ctrlKey: true }); out.delUndo = ssCell("B4"); // 병합 · Shift/Ctrl 방향 click("A4"); key("ArrowRight", { shiftKey: true }); key("ArrowRight", { shiftKey: true }); out.shift = sel(); click("A3"); key("ArrowDown", { ctrlKey: true }); out.ctrl = sel(); // 끌어 고르기 · Ctrl+Enter dragTo(at("P2"), at("Q3")); out.drag = sel(); type("=L3+1"); key("Enter", { ctrlKey: true }); out.ctrlEnter = ["P2", "Q2", "P3", "Q3"].map((k) => ssCell(k)?.식); // 수식 입력줄로 고치기 click("N2"); const bar = document.querySelector(".ss-formula"); bar.focus(); bar.value = "=J4*10"; bar.dispatchEvent(new Event("input", { bubbles: true })); key("Enter"); out.bar = [ssCell("N2"), shown("N2"), sel()]; // F2 — 방향키가 글자 자리만 click("N2"); key("F2"); const before = sel(); key("ArrowLeft"); out.f2 = [before === sel(), document.querySelector(".ss").classList.contains("ss--editing")]; key("Escape"); out.errors = window.ssErrors; return JSON.stringify(out); };