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

/**
* 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.