Files
MBN_STOCK_WEBVIEW/tests/LegacyParityWeb/explicit-modal-exit-parity.test.cjs

100 lines
4.6 KiB
JavaScript

"use strict";
const assert = require("node:assert/strict");
const fs = require("node:fs");
const path = require("node:path");
const test = require("node:test");
const repositoryRoot = path.resolve(__dirname, "..", "..");
const webRoot = path.join(repositoryRoot, "src",
"MBN_STOCK_WEBVIEW.LegacyParityApp", "Web");
const markup = fs.readFileSync(path.join(webRoot, "index.html"), "utf8");
const app = fs.readFileSync(path.join(webRoot, "app.js"), "utf8");
const styles = fs.readFileSync(path.join(webRoot, "styles.css"), "utf8");
const modalFocus = fs.readFileSync(path.join(webRoot, "legacy-modal-focus.js"), "utf8");
const inputSmoke = fs.readFileSync(path.join(
repositoryRoot, "scripts", "Test-LegacyPackageInput.mjs"), "utf8");
function section(source, startMarker, endMarker) {
const start = source.indexOf(startMarker);
assert.notEqual(start, -1, "missing start marker: " + startMarker);
const end = source.indexOf(endMarker, start + startMarker.length);
assert.ok(end > start, "missing end marker: " + endMarker);
return source.slice(start, end);
}
function navButton(tabId) {
const match = markup.match(new RegExp(
`<button[^>]*data-tab-id="${tabId}"[\\s\\S]*?<\\/button>`));
assert.ok(match, "missing navigation button: " + tabId);
return match[0];
}
test("GraphE and FSell or VI expose the original visible exit controls", () => {
assert.match(markup,
/id="manual-financial-workspace"[\s\S]*?<footer class="manual-dialog-footer">\s*<button id="manual-financial-exit" type="button">나가기<\/button>/u);
assert.match(markup,
/id="manual-list-workspace"[\s\S]*?<footer class="manual-dialog-footer">\s*<button id="manual-list-cancel" type="button">취소<\/button>/u);
assert.match(styles,
/\.manual-financial-dialog\s*\{[^}]*grid-template-rows:\s*46px minmax\(0, 1fr\) auto/u);
assert.match(styles,
/\.manual-list-dialog\s*\{[^}]*grid-template-rows:\s*46px minmax\(0, 1fr\) auto/u);
assert.match(styles, /\.manual-dialog-footer\s*\{[^}]*justify-content:\s*flex-end/u);
});
test("visible text controls reuse the exact top-close actions", () => {
const financialClose = section(
app, "function closeManualFinancial", "manualListButtons.forEach");
assert.equal((financialClose.match(/send\("close-manual-financial"/g) || []).length, 1);
assert.match(financialClose,
/manualClose\.addEventListener\("click", closeManualFinancial\)/);
assert.match(financialClose,
/manualExit\.addEventListener\("click", closeManualFinancial\)/);
const listClose = section(
app, "function closeManualList", "manualWorkspace.addEventListener");
assert.equal((listClose.match(/send\("close-manual-list"/g) || []).length, 1);
assert.match(listClose,
/manualListClose\.addEventListener\("click", closeManualList\)/);
assert.match(listClose,
/manualListCancel\.addEventListener\("click", closeManualList\)/);
});
test("text and top-close controls share locking and modal keyboard focus", () => {
assert.match(app, /manualExit\.disabled = manualClose\.disabled/);
assert.match(app, /manualListCancel\.disabled = manualListClose\.disabled/);
assert.match(app,
/setTransientControlsBusy\(manualDialog, state\.isBusy === true\)/);
assert.match(app, /setTransientControlsBusy\(manualListDialog, busy\)/);
assert.match(app,
/root\.querySelectorAll\("button, input, select, textarea"\)/);
assert.match(modalFocus,
/const focusableSelector = \[[\s\S]*?"button"[\s\S]*?\]\.join\(","\)/);
for (const id of ["manual-financial-exit", "manual-list-cancel"]) {
const button = markup.match(new RegExp(`<button id="${id}"[^>]*>`));
assert.ok(button, "missing visible close button: " + id);
assert.match(button[0], /type="button"/);
assert.doesNotMatch(button[0], /(?:disabled|tabindex="-1")/);
}
});
test("full UI input validation physically clicks the restored text controls", () => {
assert.match(inputSmoke,
/async function closeManualFinancial[\s\S]*?pointerClick\('document\.getElementById\("manual-financial-exit"\)'/);
assert.match(inputSmoke,
/async function closeManualList[\s\S]*?pointerClick\('document\.getElementById\("manual-list-cancel"\)'/);
});
test("clearer sidebar names keep the existing protocol tab IDs", () => {
const overseas = navButton("overseasStocks");
assert.match(overseas, /aria-label="해외시장"/u);
assert.match(overseas, /title="해외시장"/u);
assert.match(overseas, /<span class="workspace-nav-label">해외시장<\/span>/u);
const halt = navButton("tradingHalt");
assert.match(halt, /aria-label="거래정지"/u);
assert.match(halt, /title="거래정지"/u);
assert.match(halt, /<span class="workspace-nav-label">거래정지<\/span>/u);
});