docs(storybook): make Expanded OrgChart a preview-only page
Deploy Storybook / deploy (push) Successful in 59s
Deploy Storybook / deploy (push) Successful in 59s
Remove the data, layout, interaction and employee-popup setting panels from the Expanded OrgChart Story. The chart now renders a fixed sample (7 companies x 20, TB, all expanded, collapse/zoom/pan on, Drag & Drop off, HM Dialog) right under the page title. Story ID, OrgChart packages and public API are unchanged. Align the Story browser checks (P7, P8, P9, P9.2-P9.5, geometry, popup parity, hierarchy, HM Story) with the preview: setting-only scenarios are removed, chart rendering, collapse, Zoom/Pan/Fit and HM Dialog checks run on the fixed state. Move/Drag & Drop coverage stays in the Vanilla Core checks (verify-p9-3-core, verify-p9-4-core). Verified: tsc, test:guard 94/94, node --check on 11 scripts, changed browser sections PASS. Pre-existing P7 story-menu, P8 Department long-name, P9 Expanded tb/runner failures remain separate issues. verify-p9-5-popup-parity was not run (needs the Vanilla example server).
This commit is contained in:
1 parent
4a54cfbeb2
commit
f4ddd5ac4b
14 files changed
+163
-1134
No files matched your search
@@ -52,71 +52,38 @@ async function measure(name) {
|
||||
}
|
||||
const check = (pass, name, detail) => { checks.push({name,status:pass?'PASS':'FAIL',detail}); if (!pass) console.log('FAIL',name,JSON.stringify(detail)); };
|
||||
const centered = (s, name, vertical = false) => check(Math.abs(s.error.visible.x) < 0.75 && (!vertical || Math.abs(s.error.visible.y) < 0.75), name, s.error);
|
||||
async function select(label, option) {
|
||||
await page.getByRole('combobox', { name:label, exact:true }).click();
|
||||
await page.getByRole('option', { name:option, exact:true }).click(); await ready();
|
||||
}
|
||||
async function companies(names) {
|
||||
await page.getByRole('button',{name:/^회사 선택/}).click();
|
||||
const panel = page.getByRole('dialog',{name:'회사 선택',exact:true}); await panel.waitFor();
|
||||
const all = panel.getByRole('checkbox',{name:'전체 선택',exact:true});
|
||||
for (let i=0;i<2 && await all.getAttribute('aria-checked') !== 'false';i++) { await all.click(); await ready(); }
|
||||
await ready(0);
|
||||
if (names.length === 7) { await all.click(); await ready(140); await page.keyboard.press('Escape'); await panel.waitFor({state:'hidden'}); return; }
|
||||
for (const name of names) { await panel.getByRole('checkbox',{name,exact:true}).click(); await ready(); }
|
||||
await page.keyboard.press('Escape'); await panel.waitFor({state:'hidden'}); await ready();
|
||||
}
|
||||
async function count(count, total) {
|
||||
await select('회사당 직원 수',`${count}명`);
|
||||
const apply = page.getByRole('button',{name:'데이터 적용',exact:true}); if (await apply.isEnabled()) await apply.click(); await ready(total);
|
||||
}
|
||||
// Expanded is preview-only (2026-10-22): company/count/layout combinations are no longer
|
||||
// reachable from the Story, so only the fixed 7x20 TB state, Fit, Pan and widths are measured.
|
||||
async function open() {
|
||||
await page.goto(`${origin}/iframe.html?id=orgchart--expanded-org-chart&viewMode=story`);
|
||||
await page.getByRole('button',{name:/^회사 선택/}).waitFor(); await ready(140);
|
||||
await ready(140);
|
||||
}
|
||||
async function fit() { await page.getByRole('button',{name:'Fit to View',exact:true}).click(); await settle(); }
|
||||
try {
|
||||
await open(); const initial = await measure('initial-7x20-tb');
|
||||
await page.screenshot({path:path.join(output,`${phase}-initial.png`),fullPage:true});
|
||||
if (phase === 'after') { centered(initial,'Initial 7-company forest horizontally centered'); check(initial.scale === 1,'Initial oversized forest keeps 100% scale',initial.scale); }
|
||||
for (const [companyNames, label] of [[['한맥기술'],'one'],[['한맥기술','삼안'],'two'],[['한맥기술','삼안','장헌산업','장헌','피티씨','한라','바론'],'seven']]) {
|
||||
if (process.argv[3] && process.argv[3] !== label) continue;
|
||||
for (const size of [20,100,300]) {
|
||||
for (const [type,labelText] of [['tb','세로형 TB'],['lr','가로형 LR'],['hybrid','혼합형 Hybrid']]) {
|
||||
await open(); await companies(companyNames); await count(size,companyNames.length*size);
|
||||
await select('조직도 표시 유형',labelText);
|
||||
const s = await measure(`${label}-${size}-${type}-auto`);
|
||||
if (phase === 'after') { centered(s,`${label}/${size}/${type}: automatic horizontal center`); check(s.scale === 1,`${label}/${size}/${type}: no automatic shrink`,s.scale); }
|
||||
await fit(); const fitted = await measure(`${label}-${size}-${type}-fit`);
|
||||
if (phase === 'after') {
|
||||
centered(fitted,`${label}/${size}/${type}: Fit center both axes`,true);
|
||||
check(fitted.visible.left >= fitted.content.left+15 && fitted.visible.right <= fitted.content.left+fitted.content.width-15
|
||||
&& fitted.visible.top >= fitted.content.top+15 && fitted.visible.bottom <= fitted.content.top+fitted.content.height-15,`${label}/${size}/${type}: Fit contains visible tree`,fitted.visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
await fit(); const fitted = await measure('initial-7x20-tb-fit');
|
||||
if (phase === 'after') {
|
||||
centered(fitted,'7x20/tb: Fit center both axes',true);
|
||||
check(fitted.visible.left >= fitted.content.left+15 && fitted.visible.right <= fitted.content.left+fitted.content.width-15
|
||||
&& fitted.visible.top >= fitted.content.top+15 && fitted.visible.bottom <= fitted.content.top+fitted.content.height-15,'7x20/tb: Fit contains visible tree',fitted.visible);
|
||||
}
|
||||
if (phase === 'after') {
|
||||
// User Pan preservation across resize and deliberate content/layout changes.
|
||||
await open(); await companies(['한맥기술']); await fit();
|
||||
// User Pan preservation across resize.
|
||||
const viewport = page.locator('.hm-orgchart-viewport'); await viewport.scrollIntoViewIfNeeded(); await viewport.focus();
|
||||
await page.keyboard.press('ArrowLeft'); await page.keyboard.press('ArrowUp'); await settle();
|
||||
const panned = await measure('user-pan');
|
||||
await page.setViewportSize({width:1280,height:1100}); await ready(); const resized = await measure('pan-resize');
|
||||
await companies(['한맥기술','삼안']); const filtered = await measure('pan-company');
|
||||
await count(100,200); const changed = await measure('pan-data');
|
||||
await select('조직도 표시 유형','가로형 LR'); const switched = await measure('pan-layout');
|
||||
for (const [name,s] of [['resize',resized],['company selection',filtered],['data',changed],['layout',switched]]) {
|
||||
check(s.x===panned.x && s.y===panned.y && s.scale===panned.scale,`Manual Pan retained through ${name}`,{before:panned,after:s});
|
||||
}
|
||||
check(resized.x===panned.x && resized.y===panned.y && resized.scale===panned.scale,'Manual Pan retained through resize',{before:panned,after:resized});
|
||||
await fit(); centered(await measure('fit-after-pan'),'Explicit Fit restores center after user Pan',true);
|
||||
for (const width of [390,768,1280,1440]) {
|
||||
await page.setViewportSize({width,height:1100}); await open(); await companies(['한맥기술']);
|
||||
await page.setViewportSize({width,height:1100}); await open();
|
||||
centered(await measure(`width-${width}-initial`),`${width}px automatic horizontal center`);
|
||||
await fit(); centered(await measure(`width-${width}-fit`),`${width}px Fit center`,true);
|
||||
}
|
||||
await page.setViewportSize({width:1440,height:1100}); await open(); await companies(['한맥기술']);
|
||||
await fit(); await page.screenshot({path:path.join(output,'after-single-fit.png'),fullPage:true});
|
||||
await page.setViewportSize({width:1440,height:1100}); await open();
|
||||
await fit(); await page.screenshot({path:path.join(output,'after-fit.png'),fullPage:true});
|
||||
}
|
||||
} catch(error) { check(false,'Measurement completed',{message:error.message,stack:error.stack}); }
|
||||
check(errors.length===0,'Browser console/page errors zero',errors);
|
||||
|
||||
Reference in new issue
Block a user