test(sw): align browser tests and theme story with Noto Sans KR and Bold

Font expectations move back to Noto Sans KR (Dotum becomes the theme
inheritance verification value), viewer labels expect 700, and the new
text-weight.browser.mjs checks the requested Bold scope and outlines.
This commit is contained in:
shkim4 committed 2026-10-20 18:17:50 +09:00
1 parent 033e24246a
commit ef69f5143b
9 files changed
+205 -38

No files matched your search

@@ -1,4 +1,4 @@
// SW Footer design review (2026-10-20, Dotum default): the four open design items and the Model / Layout text rule,
// SW Footer design review (2026-10-20; SW default font Noto Sans KR since the Dotum default was withdrawn): the four open design items and the Model / Layout text rule,
// measured in the real Storybook (`SW/Footer › 전체 Footer · 실제 조합`). Computed values + element screenshots for
// each state; design judgement (PASS / REVIEW) is written in the report, this script only records facts and checks
// the approved, unambiguous rules.
@@ -10,7 +10,7 @@ import path from 'node:path'
const runtime = process.env.SW_RUNTIME_MODULES ?? 'C:/Users/user/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules'
const require = createRequire(path.join(runtime, 'index.js'))
const { chromium } = require('playwright')
const [storybook = 'http://127.0.0.1:6024', outArg = 'docs/sw/sw-dotum-font-qa/footer-design'] = process.argv.slice(2)
const [storybook = 'http://127.0.0.1:6024', outArg = 'docs/sw/sw-noto-bold-qa/footer-design'] = process.argv.slice(2)
const out = path.resolve(outArg); await mkdir(out, { recursive: true })
const results = [], facts = {}, errors = []
const check = (name, pass, detail = '') => { results.push({ name, result: pass ? 'PASS' : 'FAIL', detail }); console.log(`${pass ? 'PASS' : 'FAIL'} ${name}${detail !== '' ? ` — ${JSON.stringify(detail)}` : ''}`) }
@@ -51,7 +51,7 @@ for (const [i, label] of [[0, 'aux'], [1, 'commands']]) {
check(`전체보기(${label}) hover: both text lines #FF5C00`, h.title.color === 'rgb(255, 92, 0)' && h.sub.color === 'rgb(255, 92, 0)', [h.title.color, h.sub.color])
const rel = s => ({ w: s.box.w, h: s.box.h, tx: +(s.title.x - s.box.x).toFixed(1), ty: +(s.title.y - s.box.y).toFixed(1), tw: s.title.w, sx: +(s.sub.x - s.box.x).toFixed(1), sy: +(s.sub.y - s.box.y).toFixed(1), sw: s.sub.w })
check(`전체보기(${label}) hover: size and text boxes (relative to the button) unchanged`, JSON.stringify(rel(d)) === JSON.stringify(rel(h)), [rel(d), rel(h)])
check(`전체보기(${label}) text = Dotum 14px`, d.title.font === 'Dotum' && d.title.size === '14px', d.title.font)
check(`전체보기(${label}) text = Noto Sans KR 14px`, d.title.font === '"Noto Sans KR"' && d.title.size === '14px', d.title.font)
}
await away()
@@ -106,7 +106,7 @@ for (let i = 1; i < layoutCount; i++) {
await t.hover(); await page.waitForTimeout(150)
const h = await tabInfo(t); await shot(t, `layout-${i}-hover`, 4); await away()
facts.layoutHover.push({ i, d, h })
check(`Layout ${i} default/hover text: #161410 12px 400, same box (Dotum)`, [d, h].every(s => s.text.color === 'rgb(22, 20, 16)' && s.text.size === '12px' && s.text.weight === '400' && s.text.font === 'Dotum') && ['x', 'y', 'w', 'h'].every(k => d.text[k] === h.text[k]), `${d.text.color} → ${h.text.color}, ${d.text.w}×${d.text.h}`)
check(`Layout ${i} default/hover text: #161410 12px 400, same box (Noto Sans KR)`, [d, h].every(s => s.text.color === 'rgb(22, 20, 16)' && s.text.size === '12px' && s.text.weight === '400' && s.text.font === '"Noto Sans KR"') && ['x', 'y', 'w', 'h'].every(k => d.text[k] === h.text[k]), `${d.text.color} → ${h.text.color}, ${d.text.w}×${d.text.h}`)
}
// restore the initial selection
if (modelState !== 'on') await layoutTabs.first().locator('.hm-sw-footer-tab__select').click()
@@ -132,7 +132,7 @@ for (let i = 0; i < catNames.length; i++) {
const pocketOk = facts.categories.every(c => c.vacantBottom === null || c.vacantBottom <= c.tabTop + 1)
check('Categories: vacant surface never reaches the selected tab pocket (no split surface) — every category', pocketOk, facts.categories.map(c => `${c.name}: vacant↓${c.vacantBottom} tab↑${c.tabTop} behind=${[...new Set(c.behind)].join('/')}`))
check('Categories: one surface behind the whole pocket (left / middle / right) — every category', facts.categories.every(c => new Set(c.behind).size === 1), facts.categories.map(c => `${c.name}:${[...new Set(c.behind)].join('/')}`))
check('Categories: tab text Dotum', (await catTabs.first().evaluate(e => getComputedStyle(e).fontFamily)).startsWith('Dotum'))
check('Categories: tab text Noto Sans KR', (await catTabs.first().evaluate(e => getComputedStyle(e).fontFamily)).startsWith('"Noto Sans KR"'))
check('Console / page error 없음', errors.length === 0, errors.slice(0, 3))
await browser.close()
await writeFile(path.join(out, 'footer-design-review.json'), JSON.stringify({ storybook, results, facts, errors }, null, 2) + '\n')