63 lines
4.4 KiB
JavaScript
63 lines
4.4 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import http from 'node:http';
|
|
import path from 'node:path';
|
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
|
|
// Target only the affected existing Story and the unchanged Fixed composition.
|
|
const evidence = fileURLToPath(new URL('../test-results/org-chart-minimal-install/', import.meta.url));
|
|
const root = path.join(evidence, 'storybook');
|
|
const mime = { '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.json': 'application/json', '.svg': 'image/svg+xml', '.png': 'image/png', '.woff2': 'font/woff2' };
|
|
const server = http.createServer(async (request, response) => {
|
|
const filename = path.resolve(root, '.' + decodeURIComponent(new URL(request.url, 'http://localhost').pathname));
|
|
if (!filename.startsWith(root + path.sep)) { response.writeHead(403).end(); return; }
|
|
try { const bytes = await readFile(filename); response.writeHead(200, { 'Content-Type': mime[path.extname(filename)] || 'application/octet-stream' }).end(bytes); }
|
|
catch { response.writeHead(404).end(); }
|
|
});
|
|
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
|
|
assert.ok(process.env.ORGCHART_PLAYWRIGHT_MODULE, 'Set ORGCHART_PLAYWRIGHT_MODULE');
|
|
const { chromium } = await import(pathToFileURL(process.env.ORGCHART_PLAYWRIGHT_MODULE).href);
|
|
const browser = await chromium.launch({ headless: true, executablePath: process.env.ORGCHART_CHROME || 'C:/Program Files/Google/Chrome/Application/chrome.exe' });
|
|
const errors = [], results = [];
|
|
try {
|
|
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
|
|
page.on('pageerror', error => errors.push(error.message));
|
|
page.on('console', message => { if (message.type() === 'error') errors.push(message.text()); });
|
|
for (const id of ['orgchart--expanded-org-chart', 'orgchart--full-composition']) {
|
|
await page.goto(`http://127.0.0.1:${server.address().port}/iframe.html?id=${id}&viewMode=story`);
|
|
const card = page.locator('.hm-orgchart-employee').first();
|
|
await card.waitFor(); await card.focus(); await page.keyboard.press('Enter');
|
|
const hm = page.locator('[data-component="HMOrgChartEmployeeDialog"]');
|
|
const core = page.locator('dialog.hm-orgchart-employee-dialog');
|
|
if (id.includes('expanded')) {
|
|
await hm.waitFor({ state: 'visible' });
|
|
assert.equal(await core.evaluate(e => e.open), false);
|
|
await page.screenshot({ path: path.join(evidence, 'storybook-expanded-hm.png') });
|
|
await page.keyboard.press('Escape'); await hm.waitFor({ state: 'hidden' });
|
|
assert.equal(await card.evaluate(e => e.getRootNode().activeElement === e), true);
|
|
const trigger = page.getByRole('combobox', { name: '직원 정보 팝업' });
|
|
await trigger.click(); await page.getByRole('option', { name: 'Core 기본 팝업', exact: true }).click();
|
|
// Wait for Radix's exiting Select portal/focus restoration before opening
|
|
// another modal with the keyboard. External consumers have no Select here.
|
|
await page.getByRole('listbox').waitFor({ state: 'detached' });
|
|
await page.evaluate(() => new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve))));
|
|
await card.focus(); await page.keyboard.press('Enter');
|
|
await core.waitFor({ state: 'visible' });
|
|
assert.equal(await hm.count(), 0);
|
|
assert.equal(await core.evaluate(e => e.contains(e.getRootNode().activeElement)), true, 'Core modal receives focus after Select closes');
|
|
await page.keyboard.press('Escape'); await core.waitFor({ state: 'hidden' });
|
|
results.push({ story: id, status: 'PASS', checks: ['Existing default HM Dialog', 'Escape and focus restoration', 'Existing selector switches to Core popup'] });
|
|
} else {
|
|
await core.waitFor({ state: 'visible' }); assert.equal(await hm.count(), 0);
|
|
await page.screenshot({ path: path.join(evidence, 'storybook-fixed-core.png') });
|
|
await page.keyboard.press('Escape'); await core.waitFor({ state: 'hidden' });
|
|
results.push({ story: id, status: 'PASS', checks: ['Existing Fixed render and Core popup', 'Escape'] });
|
|
}
|
|
}
|
|
assert.deepEqual(errors, []);
|
|
await writeFile(path.join(evidence, 'storybook-browser.json'), JSON.stringify({ status: 'PASS', results, errors }, null, 2));
|
|
console.log(JSON.stringify({ status: 'PASS', results, errors }));
|
|
} finally {
|
|
await browser.close(); await new Promise(resolve => server.close(resolve));
|
|
}
|