You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/scripts/demo-probe.ts

92 lines
2.8 KiB

demos: web/routes/* for the 8 migrated soma components First demos under the new web/routes location (configured by phase C of the cleanup as `kit.files.routes`). One demo per component: toggle, switch, collapsible, avatar, dialog, drawer, popover, toast. Layout (web/routes/+layout.svelte): - Bootstraps the UIX via createActiveUix({ lang: { schema: {}, defaultLocale: 'es' } }) — minimal config, full UIX surface. - Wraps in <Uix> which sets the active-uix context and creates the Soma scope so providers can require it. - Imports the eidos index.css so the visual layer is applied. - Tiny demo-only stylesheet (web/routes/layout.css) for the page chrome (topbar, demo grid, sections) — explicitly NOT part of eidos. Each demo page exercises the public API: - toggle: bound, initially-pressed, disabled - switch: bound, disabled - collapsible: bound show/hide, disabled trigger - avatar: loaded, error fallback, delayed - dialog: basic with overlay + focus trap + escape dismissal - drawer: right / left / bottom (with handle) - popover: click + hover trigger - toast: 4 intents (fulfill, risk, threat, neutral) via createToaster Verified end-to-end with scripts/demo-probe.ts (Playwright): - All 9 routes (landing + 8 demos) serve 200. - Zero console errors except avatar's pravatar.cc network failure (sandbox limitation, not a real bug). - Interactive checks: dialog open shows modal + overlay backdrop + focused Cancel button; popover open positions floating content next to trigger; toast Fulfill shows the green-tinted shadow driven by data-event-intent='fulfill' from sema's visual channel reacting to the morfo's announce event semantics — confirms the full morfo → sema → eidos pipeline works end-to-end on a migrated soma component. scripts/demo-probe.ts: small Playwright runner that loads each route, captures console errors, takes a screenshot of the static state, then clicks the trigger on dialog/collapsible/popover/toast for a second "open" screenshot. Output goes to g:/tmp/demos/. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
/**
* Probes each demo route with Playwright. Captures console errors and
* takes a screenshot. For Dialog/Collapsible/Popover/Toast also clicks
* the trigger and captures the open state. Smoke test for the migrated
* soma components.
*
* Usage:
* 1. Start the dev server (`npm run dev`).
* 2. Adjust `BASE` to the actual port if not 5174.
* 3. `npx tsx scripts/demo-probe.ts`.
*/
import { chromium } from 'playwright';
import { mkdir } from 'node:fs/promises';
const BASE = 'http://localhost:5174';
const OUT = 'g:/tmp/demos';
const routes = [
'/',
'/toggle',
'/switch',
'/collapsible',
'/avatar',
'/dialog',
'/drawer',
'/popover',
'/toast'
];
async function main() {
await mkdir(OUT, { recursive: true });
const browser = await chromium.launch();
const ctx = await browser.newContext({ viewport: { width: 900, height: 1100 } });
const page = await ctx.newPage();
let totalErrors = 0;
for (const route of routes) {
const errors: string[] = [];
page.removeAllListeners('console');
page.removeAllListeners('pageerror');
page.on('console', (msg) => {
if (msg.type() === 'error') errors.push(msg.text());
});
page.on('pageerror', (err) => errors.push(`pageerror: ${err.message}`));
const url = BASE + route;
await page.goto(url, { waitUntil: 'networkidle' });
await page.waitForTimeout(300);
const slug = route === '/' ? 'index' : route.slice(1);
await page.screenshot({ path: `${OUT}/${slug}.png` });
// Interactive checks for components with open/close behavior.
if (route === '/dialog') {
await page.locator('[data-dialog-trigger]').first().click();
await page.waitForTimeout(400);
await page.screenshot({ path: `${OUT}/${slug}-open.png` });
} else if (route === '/collapsible') {
await page.locator('[data-collapsible-trigger]').first().click();
await page.waitForTimeout(200);
await page.screenshot({ path: `${OUT}/${slug}-open.png` });
} else if (route === '/popover') {
await page.locator('[data-popover-trigger]').first().click();
await page.waitForTimeout(400);
await page.screenshot({ path: `${OUT}/${slug}-open.png` });
} else if (route === '/toast') {
await page.locator('button:has-text("Fulfill")').first().click();
await page.waitForTimeout(400);
await page.screenshot({ path: `${OUT}/${slug}-open.png` });
}
const status = errors.length === 0 ? '✓' : `✗ ${errors.length} error(s)`;
console.log(`${status} ${route}`);
if (errors.length > 0) {
for (const e of errors) console.log(` ${e.slice(0, 200)}`);
// Avatar's network failure is a known sandbox limitation, not a real bug.
if (!(route === '/avatar' && errors.every((e) => e.includes('ERR_NAME_NOT_RESOLVED')))) {
totalErrors += errors.length;
}
}
}
await browser.close();
process.exit(totalErrors > 0 ? 1 : 0);
}
main().catch((err) => {
console.error(err);
process.exit(2);
});

Powered by TurnKey Linux.