Power and signal edges no longer act as fluid paths in the mock solver (a water demand was previously routed through the pump's power cable). Also: bundled demo diagram, visual e2e script with dev-mode editor hook, plan checklist completed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
75 lines
2.5 KiB
JavaScript
75 lines
2.5 KiB
JavaScript
/**
|
|
* Visual verification: loads the demo document through the dev hook,
|
|
* captures screenshots of (1) the routed diagram with jumpover arcs,
|
|
* (2) simulation running, (3) arcs disabled, (4) dark color scheme.
|
|
* Run: node e2e/visual.mjs (starts the dev server if needed)
|
|
*/
|
|
|
|
import { chromium } from 'playwright';
|
|
import { spawn } from 'node:child_process';
|
|
import { setTimeout as sleep } from 'node:timers/promises';
|
|
import { readFileSync } from 'node:fs';
|
|
|
|
const URL = 'http://localhost:1420';
|
|
let devServer = null;
|
|
|
|
async function serverUp() {
|
|
try {
|
|
return (await fetch(URL)).ok;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
if (!(await serverUp())) {
|
|
devServer = spawn('npm', ['run', 'dev'], { stdio: 'ignore', detached: true });
|
|
for (let i = 0; i < 60 && !(await serverUp()); i += 1) await sleep(500);
|
|
}
|
|
const doc = readFileSync(new globalThis.URL('../examples/demo.pipeline.json', import.meta.url), 'utf8');
|
|
|
|
const browser = await chromium.launch();
|
|
const page = await browser.newPage({ viewport: { width: 1500, height: 950 } });
|
|
page.on('pageerror', (e) => console.error('[pageerror]', String(e)));
|
|
await page.goto(URL);
|
|
await page.waitForSelector('[data-testid="canvas"] svg');
|
|
await page.waitForFunction(() => !!window.__editor);
|
|
|
|
await page.evaluate((json) => {
|
|
window.__editor.loadDocumentJSON(json);
|
|
window.__editor.zoomToFit();
|
|
}, doc);
|
|
await sleep(600);
|
|
await page.screenshot({ path: 'e2e/visual-routing.png' });
|
|
console.log('✓ e2e/visual-routing.png (manhattan routing + jumpover arcs)');
|
|
|
|
await page.click('[data-testid="simulate-button"]');
|
|
await sleep(900);
|
|
await page.screenshot({ path: 'e2e/visual-simulation.png' });
|
|
console.log('✓ e2e/visual-simulation.png (animated flow, labels)');
|
|
await page.click('[data-testid="simulate-button"]');
|
|
|
|
await page.evaluate(() => {
|
|
window.__editor.applyConfig({ ...window.__editor.config, arcOnIntersections: false });
|
|
});
|
|
await sleep(500);
|
|
await page.screenshot({ path: 'e2e/visual-no-arcs.png' });
|
|
console.log('✓ e2e/visual-no-arcs.png (arcs disabled)');
|
|
|
|
await page.evaluate(() => {
|
|
window.__editor.applyConfig({ ...window.__editor.config, arcOnIntersections: true, colorScheme: 'dark' });
|
|
});
|
|
await sleep(500);
|
|
await page.screenshot({ path: 'e2e/visual-dark.png' });
|
|
console.log('✓ e2e/visual-dark.png (dark scheme)');
|
|
|
|
await browser.close();
|
|
if (devServer) process.kill(-devServer.pid);
|
|
}
|
|
|
|
main().catch((e) => {
|
|
console.error(e);
|
|
if (devServer) process.kill(-devServer.pid);
|
|
process.exit(1);
|
|
});
|