fix(org-chart): improve auto connector contrast and test portability

This commit is contained in:
shkim4 committed 2026-10-12 22:54:15 +09:00
1 parent d2b76e7664
commit 7644520cee
21 files changed
+109 -61

No files matched your search

@@ -1,3 +1,4 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import assert from 'node:assert/strict';
import http from 'node:http';
import path from 'node:path';
@@ -5,7 +6,7 @@ import { readFile, writeFile } from 'node:fs/promises';
import { fileURLToPath, pathToFileURL } from 'node:url';
const root = fileURLToPath(new URL('../../', import.meta.url));
const { chromium } = await import(process.env.ORGCHART_PLAYWRIGHT_MODULE ? pathToFileURL(process.env.ORGCHART_PLAYWRIGHT_MODULE).href : 'playwright');
await loadPlaywright();
const server = http.createServer(async (request, response) => {
try {
const url = new URL(request.url, 'http://localhost');
@@ -18,7 +19,7 @@ const server = http.createServer(async (request, response) => {
} catch { response.writeHead(404).end(); }
});
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
const browser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME || 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', headless: true });
const browser = await launchChromium({ headless: true });
const results = [], errors = [];
const check = (condition, name, detail) => { results.push({ name, status: condition ? 'PASS' : 'FAIL', detail }); assert.ok(condition, name); };
try {
+4 -4
View File
@@ -1,14 +1,14 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import assert from 'node:assert/strict';
import http from 'node:http';
import path from 'node:path';
import { readFile, mkdir, writeFile } from 'node:fs/promises';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { fileURLToPath } from 'node:url';
const root = fileURLToPath(new URL('../../', import.meta.url));
const output = path.join(root, 'test-results/org-chart-react');
await mkdir(output, { recursive: true });
const modulePath = process.env.ORGCHART_PLAYWRIGHT_MODULE;
const { chromium } = await import(modulePath ? pathToFileURL(modulePath).href : 'playwright');
await loadPlaywright();
const mime = { '.html': 'text/html', '.js': 'text/javascript', '.json': 'application/json', '.css': 'text/css', '.ttf': 'font/ttf', '.woff2': 'font/woff2', '.svg': 'image/svg+xml' };
async function serve(directory) {
const server = http.createServer(async (request, response) => {
@@ -27,7 +27,7 @@ async function serve(directory) {
const consumer = await serve(path.join(root, 'examples/org-chart-react/dist'));
const vanilla = await serve(path.join(root, 'examples/org-chart/dist'));
const storybook = await serve(path.join(root, 'storybook-static'));
const browser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME || 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', headless: true });
const browser = await launchChromium({ headless: true });
const results = [], errors = [], metrics = [], snapshots = {};
function check(condition, name, detail) {
results.push({ name, status: condition ? 'PASS' : 'FAIL', detail });
+4 -3
View File
@@ -1,14 +1,15 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import http from 'node:http';
import path from 'node:path';
import { readFile, writeFile, mkdir } from 'node:fs/promises';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { fileURLToPath } from 'node:url';
// Stage 2 only: typography, data placement, overflow and accessible tooltip.
// Do not repeat Stage 1's gradient/data/Summary/engine suites.
const root = fileURLToPath(new URL('../../', import.meta.url));
const output = path.join(root, 'test-results/org-chart-card-content');
await mkdir(output, { recursive: true });
const { chromium } = await import(process.env.ORGCHART_PLAYWRIGHT_MODULE ? pathToFileURL(process.env.ORGCHART_PLAYWRIGHT_MODULE).href : 'playwright');
await loadPlaywright();
const results = [], errors = [], measurements = [], servers = [];
const check = (value, name, detail) => results.push({ name, status: value ? 'PASS' : 'FAIL', ...(detail === undefined ? {} : { detail }) });
const mime = { '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.json': 'application/json', '.ttf': 'font/ttf' };
@@ -135,7 +136,7 @@ async function tooltipChecks(page, label) {
let browser;
try {
const origins = await Promise.all(['storybook-static', 'examples/org-chart/dist', 'examples/org-chart-react/dist'].map(directory => serve(path.join(root, directory))));
browser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME ?? 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', headless: true });
browser = await launchChromium({ headless: true });
const context = await browser.newContext({ viewport: { width: 1440, height: 1000 }, reducedMotion: 'reduce' });
const routes = [['department-colors', `${origins[0]}/iframe.html?id=orgchart--department-colors&viewMode=story`],
['full-composition', `${origins[0]}/iframe.html?id=orgchart--full-composition&viewMode=story`], ['html', `${origins[1]}/p1.html`], ['react', `${origins[2]}/p1.html`]];
+3 -2
View File
@@ -1,3 +1,4 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import http from 'node:http';
import path from 'node:path';
import { readFile, writeFile, mkdir, readdir } from 'node:fs/promises';
@@ -8,7 +9,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
const root = fileURLToPath(new URL('../../', import.meta.url));
const output = path.join(root, 'test-results/org-chart-card-design');
await mkdir(output, { recursive: true });
const { chromium } = await import(process.env.ORGCHART_PLAYWRIGHT_MODULE ? pathToFileURL(process.env.ORGCHART_PLAYWRIGHT_MODULE).href : 'playwright');
await loadPlaywright();
const results = [], measurements = [], errors = [], servers = [];
const check = (value, name, detail) => results.push({ name, status: value ? 'PASS' : 'FAIL', ...(detail === undefined ? {} : { detail }) });
const mime = { '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.json': 'application/json', '.ttf': 'font/ttf', '.svg': 'image/svg+xml' };
@@ -91,7 +92,7 @@ function verify(value, label) {
let browser;
try {
const origins = await Promise.all(['storybook-static', 'examples/org-chart/dist', 'examples/org-chart-react/dist'].map(directory => serve(path.join(root, directory))));
browser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME ?? 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', headless: true });
browser = await launchChromium({ headless: true });
const context = await browser.newContext({ viewport: { width: 1440, height: 1000 }, deviceScaleFactor: 1, reducedMotion: 'reduce' });
const index = JSON.parse(await readFile(path.join(root, 'storybook-static/index.json'), 'utf8'));
const entries = Object.values(index.entries).filter(entry => entry.type === 'story' && entry.title.startsWith('OrgChart'));
@@ -1,15 +1,15 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import { readFile, writeFile, mkdir } from 'node:fs/promises';
import { pathToFileURL } from 'node:url';
import { createHash } from 'node:crypto';
// Only the eight final card requirements; existing 368-check evidence is untouched.
const { chromium } = await import(pathToFileURL(process.env.ORGCHART_PLAYWRIGHT_MODULE).href);
await loadPlaywright();
const output = 'test-results/org-chart-final-check';
await mkdir(output, { recursive: true });
const fixture = JSON.parse(await readFile('examples/org-chart/data-p1.json', 'utf8'));
const results = [], measurements = [], errors = [];
const check = (ok, name, actual) => results.push({ name, status: ok ? 'PASS' : 'FAIL', actual });
const browser = await chromium.launch({ executablePath: 'C:/Program Files/Google/Chrome/Application/chrome.exe', headless: true });
const browser = await launchChromium({ headless: true });
const origin = process.env.ORGCHART_STORY_ORIGIN ?? 'http://127.0.0.1:6031';
const collisionRepair = process.argv.includes('--collision-repair');
async function capture(story, scenario, data) {
@@ -1,10 +1,10 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import { readFile, writeFile } from 'node:fs/promises';
import { pathToFileURL } from 'node:url';
const { chromium } = await import(pathToFileURL(process.env.ORGCHART_PLAYWRIGHT_MODULE).href);
await loadPlaywright();
const output = 'test-results/org-chart-final-check';
const baselineMode = process.argv.includes('--baseline');
const repairMode = process.argv.includes('--geometry-repair');
const browser = await chromium.launch({ executablePath: 'C:/Program Files/Google/Chrome/Application/chrome.exe', headless: true });
const browser = await launchChromium({ headless: true });
const measurements = [], results = [], errors = [];
const check = (ok, name, actual) => results.push({ name, status: ok ? 'PASS' : 'FAIL', actual });
const previous = baselineMode ? [] : JSON.parse(await readFile(`${output}/logo-before.json`, 'utf8'));
@@ -1,12 +1,12 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import http from 'node:http';
import path from 'node:path';
import { readFile, writeFile } from 'node:fs/promises';
import { pathToFileURL } from 'node:url';
const { chromium } = await import(pathToFileURL(process.env.ORGCHART_PLAYWRIGHT_MODULE).href);
await loadPlaywright();
const output = 'test-results/org-chart-final-check';
const baselineMode = process.argv.includes('--baseline');
const colorsRepair = process.argv.includes('--colors-repair');
const browser = await chromium.launch({ executablePath: 'C:/Program Files/Google/Chrome/Application/chrome.exe', headless: true });
const browser = await launchChromium({ headless: true });
const results = [], measurements = [], errors = [];
const check = (ok, name, actual) => results.push({ name, status: ok ? 'PASS' : 'FAIL', actual });
async function measure(url, label) {
+5 -5
View File
@@ -1,15 +1,15 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import http from 'node:http';
import path from 'node:path';
import { readFile, mkdir, writeFile } from 'node:fs/promises';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { fileURLToPath } from 'node:url';
// Verification tooling is supplied by the environment, never shipped in Core.
const root = fileURLToPath(new URL('../../', import.meta.url));
const output = path.join(root, 'test-results/org-chart-p1');
await mkdir(output, { recursive: true });
const fixture = JSON.parse(await readFile(path.join(root, 'examples/org-chart/data-p1.json'), 'utf8'));
const modulePath = process.env.ORGCHART_PLAYWRIGHT_MODULE;
const { chromium } = await import(modulePath ? pathToFileURL(modulePath).href : 'playwright');
await loadPlaywright();
const mime = { '.html': 'text/html', '.js': 'text/javascript', '.json': 'application/json', '.css': 'text/css', '.ttf': 'font/ttf', '.woff2': 'font/woff2', '.png': 'image/png', '.svg': 'image/svg+xml' };
async function serve(directory) {
const server = http.createServer(async (request, response) => {
@@ -306,7 +306,7 @@ async function recheckStorybookConsole() {
let retryBrowser;
let sidebar;
try {
retryBrowser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME || 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', headless: true });
retryBrowser = await launchChromium({ headless: true });
const context = await retryBrowser.newContext({ viewport: { width: 1440, height: 1080 } });
const iframe = await context.newPage();
iframe.on('pageerror', error => retryErrors.push({ surface: 'iframe', type: 'pageerror', message: error.message }));
@@ -361,7 +361,7 @@ try {
const vanilla = await serve(path.join(root, 'examples/org-chart/dist')); servers.push(vanilla);
const react = await serve(path.join(root, 'examples/org-chart-react/dist')); servers.push(react);
const storybook = await serve(path.join(root, 'storybook-static')); servers.push(storybook);
browser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME || 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', headless: true });
browser = await launchChromium({ headless: true });
const context = await browser.newContext({ viewport: { width: 1440, height: 1080 } });
const pages = new Map();
for (const [transport, origin] of [['vanilla', vanilla.origin], ['react', react.origin]]) {
+3 -3
View File
@@ -1,3 +1,4 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import http from 'node:http';
import path from 'node:path';
import { readFile, mkdir, writeFile } from 'node:fs/promises';
@@ -14,8 +15,7 @@ const fixturePath = path.join(root, 'examples/org-chart/data-p1.json');
const fixtureBytes = await readFile(fixturePath);
const fixtureHash = createHash('sha256').update(fixtureBytes).digest('hex');
const fixture = JSON.parse(fixtureBytes.toString('utf8'));
const bundledPlaywright = 'C:\\Users\\user\\.cache\\codex-runtimes\\codex-primary-runtime\\dependencies\\node\\node_modules\\playwright\\index.mjs';
const { chromium } = await import(pathToFileURL(process.env.ORGCHART_PLAYWRIGHT_MODULE ?? bundledPlaywright).href);
await loadPlaywright();
const viewports = [{ width: 1920, height: 1080 }, { width: 1440, height: 900 }, { width: 1280, height: 800 }, { width: 768, height: 1024 }, { width: 390, height: 844 }];
const expectedArrows = [[194.15, 311.75, 66.25, 19.8], [430.4, 311.75, 66.25, 19.8], [666.65, 302, 183.75, 42], [1044, 302, 258.92, 42], [1520.55, 305, 135.35, 36]];
const results = [], measurements = [], errors = [], screenshots = [], servers = [];
@@ -275,7 +275,7 @@ let browser;
try {
const [htmlOrigin, reactOrigin] = await Promise.all([serve(path.join(root, 'examples/org-chart/dist')), serve(path.join(root, 'examples/org-chart-react/dist'))]);
const storybookOrigin = process.env.ORGCHART_STORYBOOK_URL?.replace(/\/$/, '') ?? await serve(path.join(root, 'storybook-static'));
browser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME ?? 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', headless: true });
browser = await launchChromium({ headless: true });
const context = await browser.newContext({ deviceScaleFactor: 1, reducedMotion: 'reduce' });
const routes = [
{ label: 'html', transport: 'html', url: `${htmlOrigin}/p1.html?mode=readOnly` },
+3 -2
View File
@@ -1,3 +1,4 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import http from 'node:http';
import path from 'node:path';
import fs from 'node:fs/promises';
@@ -9,7 +10,7 @@ const root = fileURLToPath(new URL('../../', import.meta.url));
const output = path.join(root, 'test-results/org-chart-p3.1');
const fixtureBytes = await fs.readFile(path.join(root, 'examples/org-chart/data-p1.json'));
const fixture = JSON.parse(fixtureBytes);
const { chromium } = await import(pathToFileURL(process.env.ORGCHART_PLAYWRIGHT_MODULE ?? 'C:/Users/user/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright/index.mjs').href);
await loadPlaywright();
const viewports = [{ width: 1920, height: 1080 }, { width: 1440, height: 900 }, { width: 1280, height: 800 }, { width: 768, height: 1024 }, { width: 390, height: 844 }];
const results = [], measurements = [], fontEvidence = [], errors = [], servers = [];
const check = (pass, name, detail) => results.push({ name, status: pass ? 'PASS' : 'FAIL', ...(detail === undefined ? {} : { detail }) });
@@ -139,7 +140,7 @@ let browser;
try {
const htmlOrigin = await serve(path.join(root,'examples/org-chart/dist'));
const reactOrigin = await serve(path.join(root,'examples/org-chart-react/dist'));
browser = await chromium.launch({executablePath:process.env.ORGCHART_CHROME ?? 'C:/Program Files/Google/Chrome/Application/chrome.exe',headless:true});
browser = await launchChromium({ headless: true });
const context = await browser.newContext();
const routes = [{name:'html',url:`${htmlOrigin}/p1.html?mode=readOnly`},{name:'file-classic',url:pathToFileURL(path.join(root,'examples/org-chart/dist/p1-classic.html')).href+'?mode=readOnly'},{name:'react',url:`${reactOrigin}/p1.html?mode=readOnly`},{name:'storybook',url:'http://127.0.0.1:6041/iframe.html?id=orgchart--full-composition&viewMode=story'}];
for(const route of routes) {
+3 -2
View File
@@ -1,3 +1,4 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import http from 'node:http';
import path from 'node:path';
import fs from 'node:fs/promises';
@@ -11,7 +12,7 @@ const baselineMode = process.argv.includes('--baseline');
const policiesOnly = process.argv.includes('--policies-only');
const fixtureBytes = await fs.readFile(path.join(root, 'examples/org-chart/data-p1.json'));
const fixture = JSON.parse(fixtureBytes);
const { chromium } = await import(pathToFileURL(process.env.ORGCHART_PLAYWRIGHT_MODULE ?? 'C:/Users/user/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright/index.mjs').href);
await loadPlaywright();
const viewports = [{ width: 1920, height: 1080 }, { width: 1440, height: 900 }, { width: 1280, height: 800 }, { width: 768, height: 1024 }, { width: 390, height: 844 }];
const storyOrigin = process.env.ORGCHART_STORY_ORIGIN ?? 'http://127.0.0.1:6041';
const results = [], measurements = [], errors = [], servers = [];
@@ -200,7 +201,7 @@ let browser;
try {
const htmlOrigin = await serve(path.join(root, 'examples/org-chart/dist'));
const reactOrigin = await serve(path.join(root, 'examples/org-chart-react/dist'));
browser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME ?? 'C:/Program Files/Google/Chrome/Application/chrome.exe', headless: true });
browser = await launchChromium({ headless: true });
const context = await browser.newContext();
const routes = [{ name: 'html', url: `${htmlOrigin}/p1.html?mode=readOnly`, origin: htmlOrigin }, { name: 'file-classic', url: pathToFileURL(path.join(root, 'examples/org-chart/dist/p1-classic.html')).href + '?mode=readOnly' }, { name: 'react', url: `${reactOrigin}/p1.html?mode=readOnly`, origin: reactOrigin }, { name: 'storybook', url: `${storyOrigin}/iframe.html?id=orgchart--full-composition&viewMode=story` }];
for (const route of routes) {
+3 -3
View File
@@ -1,3 +1,4 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import http from 'node:http';
import path from 'node:path';
import { readFile, mkdir, writeFile } from 'node:fs/promises';
@@ -13,8 +14,7 @@ const fixturePath = path.join(root, 'examples/org-chart/data-p1.json');
const fixtureBytes = await readFile(fixturePath);
const fixtureHash = createHash('sha256').update(fixtureBytes).digest('hex');
const fixture = JSON.parse(fixtureBytes.toString('utf8'));
const playwrightPath = process.env.ORGCHART_PLAYWRIGHT_MODULE ?? 'C:\\Users\\user\\.cache\\codex-runtimes\\codex-primary-runtime\\dependencies\\node\\node_modules\\playwright\\index.mjs';
const { chromium } = await import(pathToFileURL(playwrightPath).href);
await loadPlaywright();
const viewports = [{ width: 1920, height: 1080 }, { width: 1440, height: 900 }, { width: 1280, height: 800 }, { width: 768, height: 1024 }, { width: 390, height: 844 }];
const results = [], measurements = [], interactions = [], errors = [], screenshots = [], servers = [];
const check = (condition, name, detail) => results.push({ name, status: condition ? 'PASS' : 'FAIL', ...(detail === undefined ? {} : { detail }) });
@@ -333,7 +333,7 @@ try {
// The user identified the live 6041 Storybook; never silently verify a stale
// storybook-static build from P2 instead of that requested running server.
const storybookOrigin = process.env.ORGCHART_STORYBOOK_URL?.replace(/\/$/, '') ?? 'http://127.0.0.1:6041';
browser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME ?? 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', headless: true });
browser = await launchChromium({ headless: true });
const context = await browser.newContext({ deviceScaleFactor: 1, reducedMotion: 'reduce' });
const routes = [
{ label: 'html', transport: 'html', url: `${htmlOrigin}/p1.html?mode=readOnly` },
+4 -4
View File
@@ -1,15 +1,15 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import http from 'node:http';
import path from 'node:path';
import fs from 'node:fs/promises';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { fileURLToPath } from 'node:url';
// P5-1A only: preserve previous suites and the baseline-files.json snapshot.
// Copy the pre-change public Core dist to baseline-dist before rebuilding.
const root = fileURLToPath(new URL('../../', import.meta.url));
const output = path.join(root, 'test-results/org-chart-p5-1a');
const storyOrigin = process.env.ORGCHART_STORY_ORIGIN ?? 'http://127.0.0.1:6052';
const { chromium } = await import(pathToFileURL(process.env.ORGCHART_PLAYWRIGHT_MODULE
?? 'C:/Users/user/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright/index.mjs').href);
const { chromium } = await loadPlaywright();
const fixedFixture = JSON.parse(await fs.readFile(path.join(root, 'examples/org-chart/data-p1.json'), 'utf8'));
const expandedFixture = JSON.parse(await fs.readFile(path.join(root, 'examples/org-chart/data-expanded.json'), 'utf8'));
const presets = [
@@ -44,7 +44,7 @@ const server = http.createServer(async (request, response) => {
});
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
const origin = `http://127.0.0.1:${server.address().port}`;
const browser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME ?? 'C:/Program Files/Google/Chrome/Application/chrome.exe', headless: true });
const browser = await launchChromium({ headless: true });
async function newPage(name, viewport = { width: 1440, height: 900 }) {
const page = await browser.newPage({ viewport });
+4 -4
View File
@@ -1,15 +1,15 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import http from 'node:http';
import path from 'node:path';
import fs from 'node:fs/promises';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { fileURLToPath } from 'node:url';
// P5-1B focused integration suite. Preserve historical verification evidence.
// Copy the pre-change public Core dist to baseline-dist before rebuilding.
const root = fileURLToPath(new URL('../../', import.meta.url));
const output = path.join(root, 'test-results/org-chart-p5-1b');
const storyOrigin = process.env.ORGCHART_STORY_ORIGIN ?? 'http://127.0.0.1:6053';
const playwright = process.env.ORGCHART_PLAYWRIGHT_MODULE;
const { chromium } = await import(playwright ? pathToFileURL(playwright).href : 'playwright');
await loadPlaywright();
const fixedFixture = JSON.parse(await fs.readFile(path.join(root, 'examples/org-chart/data-p1.json'), 'utf8'));
const expandedFixture = JSON.parse(await fs.readFile(path.join(root, 'examples/org-chart/data-expanded.json'), 'utf8'));
const presets = [
@@ -44,7 +44,7 @@ const server = http.createServer(async (request, response) => {
});
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
const origin = `http://127.0.0.1:${server.address().port}`;
const browser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME ?? 'C:/Program Files/Google/Chrome/Application/chrome.exe', headless: true });
const browser = await launchChromium({ headless: true });
async function newPage(name, viewport = { width: 1440, height: 900 }) {
const page = await browser.newPage({ viewport });
+4 -4
View File
@@ -1,11 +1,11 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import fs from 'node:fs/promises';
import http from 'node:http';
import path from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { fileURLToPath } from 'node:url';
const root = fileURLToPath(new URL('../../', import.meta.url));
const output = path.join(root, 'test-results/org-chart-p5-23');
const playwright = process.env.ORGCHART_PLAYWRIGHT_MODULE;
const { chromium } = await import(playwright ? pathToFileURL(playwright).href : 'playwright');
await loadPlaywright();
const story = process.env.ORGCHART_STORY_ORIGIN ?? 'http://127.0.0.1:6054';
const html = process.env.ORGCHART_HTML_ORIGIN ?? 'http://127.0.0.1:4189';
const fixtures = Object.fromEntries(await Promise.all(['small', 'medium', 'large'].map(async size => [size, JSON.parse(await fs.readFile(path.join(root, `examples/org-chart/data-expanded-${size}.json`), 'utf8'))])));
@@ -25,7 +25,7 @@ const server = http.createServer(async (request, response) => {
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
const origin = `http://127.0.0.1:${server.address().port}`;
await fs.mkdir(output, { recursive: true });
const browser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME ?? 'C:/Program Files/Google/Chrome/Application/chrome.exe', headless: true });
const browser = await launchChromium({ headless: true });
const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
page.on('pageerror', error => errors.push(error.message));
page.on('console', message => { if (message.type() === 'error') errors.push(message.text()); });
+4 -4
View File
@@ -1,13 +1,13 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
// Focused P5-4 checks. Does not replay P5-1B/P5-23 suites or performance timings.
import fs from 'node:fs/promises';
import { writeFileSync } from 'node:fs';
import http from 'node:http';
import path from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { fileURLToPath } from 'node:url';
const root = fileURLToPath(new URL('../../', import.meta.url));
const output = path.join(root, 'test-results/org-chart-p5-4');
const playwright = process.env.ORGCHART_PLAYWRIGHT_MODULE;
const { chromium } = await import(playwright ? pathToFileURL(playwright).href : 'playwright');
await loadPlaywright();
const fixtures = Object.fromEntries(await Promise.all(['small', 'medium', 'large'].map(async size => [size, JSON.parse(await fs.readFile(path.join(root, `examples/org-chart/data-expanded-${size}.json`), 'utf8'))])));
const fixed = JSON.parse(await fs.readFile(path.join(root, 'examples/org-chart/data-p1.json'), 'utf8'));
const results = [], errors = [], measurements = [];
@@ -37,7 +37,7 @@ const server = http.createServer(async (request, response) => {
await fs.mkdir(output, { recursive: true });
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
const origin = `http://127.0.0.1:${server.address().port}`;
const browser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME ?? 'C:/Program Files/Google/Chrome/Application/chrome.exe', headless: true });
const browser = await launchChromium({ headless: true });
const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
const track = p => { p.on('pageerror', e => errors.push(e.message)); p.on('console', m => { if (m.type() === 'error') errors.push({message:m.text(),location:m.location()}); }); };
track(page);
@@ -1,7 +1,7 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import { writeFile } from 'node:fs/promises';
import { pathToFileURL } from 'node:url';
const { chromium } = await import(pathToFileURL(process.env.ORGCHART_PLAYWRIGHT_MODULE).href);
const browser = await chromium.launch({ executablePath: 'C:/Program Files/Google/Chrome/Application/chrome.exe', headless: true });
await loadPlaywright();
const browser = await launchChromium({ headless: true });
try {
const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
await page.goto('http://127.0.0.1:6027/iframe.html?id=orgchart--full-composition&viewMode=story');
+4 -3
View File
@@ -1,14 +1,15 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import http from 'node:http';
import path from 'node:path';
import { readFile, writeFile, mkdir } from 'node:fs/promises';
import { createHash } from 'node:crypto';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { fileURLToPath } from 'node:url';
// Quality-only verification. No data/source/lifecycle regression suite is run.
const root = fileURLToPath(new URL('../../', import.meta.url));
const output = path.join(root, 'test-results/org-chart-quality');
await mkdir(output, { recursive: true });
const { chromium } = await import(process.env.ORGCHART_PLAYWRIGHT_MODULE ? pathToFileURL(process.env.ORGCHART_PLAYWRIGHT_MODULE).href : 'playwright');
await loadPlaywright();
const results = [], errors = [], measurements = [], screenshots = [];
const check = (value, name, detail) => results.push({ name, status: value ? 'PASS' : 'FAIL', ...(detail === undefined ? {} : { detail }) });
const mime = { '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.json': 'application/json', '.png': 'image/png', '.ttf': 'font/ttf' };
@@ -108,7 +109,7 @@ let browser;
const servers = [];
try {
for (const directory of ['storybook-static', 'examples/org-chart/dist', 'examples/org-chart-react/dist']) servers.push(await serve(path.join(root, directory)));
browser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME ?? 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', headless: true });
browser = await launchChromium({ headless: true });
const context = await browser.newContext({ viewport: { width: 1440, height: 1000 }, deviceScaleFactor: 1, reducedMotion: 'reduce' });
const canonical = ['logo', 'department-colors', 'position-summary', 'affiliation-summary', 'full-composition'];
const index = JSON.parse(await readFile(path.join(root, 'storybook-static/index.json'), 'utf8'));
+3 -3
View File
@@ -1,3 +1,4 @@
import { loadPlaywright, launchChromium } from '../../scripts/orgchart-browser-runtime.mjs';
import assert from 'node:assert/strict';
import http from 'node:http';
import { readFile, mkdir, writeFile } from 'node:fs/promises';
@@ -5,8 +6,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
import path from 'node:path';
// Browser tooling belongs to the verification environment, not the production package.
const playwright = process.env.ORGCHART_PLAYWRIGHT_MODULE;
const { chromium } = await import(playwright ? pathToFileURL(playwright).href : 'playwright');
await loadPlaywright();
const example = fileURLToPath(new URL('./dist/', import.meta.url));
const output = fileURLToPath(new URL('../../test-results/org-chart-browser/', import.meta.url));
await mkdir(output, { recursive: true });
@@ -24,7 +24,7 @@ const server = http.createServer(async (request, response) => {
});
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
const origin = `http://127.0.0.1:${server.address().port}`;
const browser = await chromium.launch({ executablePath: process.env.ORGCHART_CHROME || 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', headless: true });
const browser = await launchChromium({ headless: true });
const results = [], errors = [], metrics = [];
const check = (condition, name, detail) => { results.push({ name, status: condition ? 'PASS' : 'FAIL', detail }); assert.ok(condition, `${name}: ${JSON.stringify(detail)}`); };
try {
@@ -6,6 +6,8 @@
--hm-orgchart-expanded-title-gap: var(--hm-orgchart-resolved-spacing-md);
--hm-orgchart-expanded-employee-gap: var(--hm-orgchart-resolved-spacing-md);
--hm-orgchart-expanded-line-width: var(--hm-orgchart-resolved-border-width);
/* Meaningful Auto relationships: separate from neutral card/Fixed borders. */
--hm-orgchart-expanded-line-color: #738399;
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: var(--hm-orgchart-resolved-spacing-lg);
@@ -101,6 +103,7 @@
width: 100%;
height: 0;
border-width: var(--hm-orgchart-expanded-line-width) 0 0;
border-color: var(--hm-orgchart-expanded-line-color);
}
.hm-orgchart-expanded .hm-orgchart-engine.orgchart .hierarchy:has(> .node[data-depth]) > .nodes > .hierarchy:first-child::before { left: calc(50% - 1px); width: calc(50% + 1px); }
.hm-orgchart-expanded .hm-orgchart-engine.orgchart .hierarchy:has(> .node[data-depth]) > .nodes > .hierarchy:last-child::before { width: calc(50% + 1px); }
@@ -109,11 +112,13 @@
top: calc(-1 * var(--hm-orgchart-expanded-level-gap) / 2);
height: calc(var(--hm-orgchart-expanded-level-gap) / 2);
width: var(--hm-orgchart-expanded-line-width);
background-color: var(--hm-orgchart-expanded-line-color);
}
.hm-orgchart-expanded .hm-orgchart-engine.orgchart .hierarchy:not(.couple) > .node:has(+ .nodes)::after {
bottom: calc(-1 * var(--hm-orgchart-expanded-level-gap) / 2);
height: calc(100% - var(--hm-orgchart-expanded-content-height) + var(--hm-orgchart-expanded-level-gap) / 2);
width: var(--hm-orgchart-expanded-line-width);
background-color: var(--hm-orgchart-expanded-line-color);
}
/* Standalone content variables, independent of Fixed and HM React controls. */
@@ -162,7 +167,7 @@
padding-inline: var(--hm-orgchart-resolved-spacing-xxl);
}
.hm-orgchart-expanded .hm-orgchart-employee-connectors { position: absolute; inset: 0; overflow: visible; pointer-events: none; }
.hm-orgchart-expanded .hm-orgchart-employee-connectors path { fill: none; stroke: var(--hm-orgchart-resolved-stroke-default); stroke-width: var(--hm-orgchart-expanded-line-width); }
.hm-orgchart-expanded .hm-orgchart-employee-connectors path { fill: none; stroke: var(--hm-orgchart-expanded-line-color); stroke-width: var(--hm-orgchart-expanded-line-width); }
.hm-orgchart-expanded .hm-orgchart-engine.orgchart .node[data-depth] .hm-orgchart-employee[data-card-presentation="expanded"] {
padding: var(--hm-orgchart-expanded-card-padding);
border-radius: var(--hm-orgchart-expanded-card-radius);
+37
View File
@@ -0,0 +1,37 @@
import path from 'node:path';
import { pathToFileURL } from 'node:url';
let playwrightPromise;
// Resolve project dependencies normally; an external installation is optional.
export async function loadPlaywright() {
playwrightPromise ??= (async () => {
const modulePath = process.env.ORGCHART_PLAYWRIGHT_MODULE?.trim();
try {
const runtime = await import(modulePath ? pathToFileURL(path.resolve(modulePath)).href : 'playwright');
if (typeof runtime.chromium?.launch !== 'function') throw new Error('Module does not export chromium.launch');
return runtime;
} catch (cause) {
throw new Error(
`OrgChart browser verification cannot load Playwright (${modulePath || 'project module: playwright'}). ` +
'Use an existing project Playwright installation, or set ORGCHART_PLAYWRIGHT_MODULE to an existing Playwright entry file.',
{ cause },
);
}
})();
return playwrightPromise;
}
export async function launchChromium(options = {}) {
const { chromium } = await loadPlaywright();
const executablePath = process.env.ORGCHART_CHROME?.trim();
try {
return await chromium.launch({ ...options, ...(executablePath ? { executablePath: path.resolve(executablePath) } : {}) });
} catch (cause) {
throw new Error(
`OrgChart browser verification cannot launch Chromium (${executablePath || 'Playwright-managed browser'}). ` +
'Ensure this Playwright installation has its Chromium browser, or set ORGCHART_CHROME to an existing browser executable.',
{ cause },
);
}
}