ui/tools/test.cjs

62 lines
3.0 KiB
JavaScript
Raw Normal View History

const { spawn } = require('node:child_process');
const { mkdtemp, rm } = require('node:fs/promises');
const { tmpdir } = require('node:os');
const { join } = require('node:path');
const net = require('node:net');
const { chromium } = require('playwright');
const root = join(__dirname, '..');
const aliases = { DataGrid: 'components/data/DataGrid.test.html', 'data.DataGrid': 'components/data/DataGrid.test.html' };
const requested = process.argv[2];
const pages = requested
? [aliases[requested] || `components/${requested.replace('.', '/')}.test.html`]
: ['components/base/API.test.html', 'components/base/AutoForm.test.html', 'components/base/Modal.test.html', 'components/base/Nav.test.html', 'components/data/DataGrid.test.html'];
const getPort = () => new Promise((resolve, reject) => {
const server = net.createServer();
server.once('error', reject);
server.listen(0, '127.0.0.1', () => { const { port } = server.address(); server.close(() => resolve(port)); });
});
const waitFor = async (url, timeout = 10000) => {
const started = Date.now();
while (Date.now() - started < timeout) {
try { if ((await fetch(url)).ok) return; } catch (_) { }
await new Promise(resolve => setTimeout(resolve, 100));
}
throw new Error(`Timed out waiting for ${url}`);
};
(async () => {
const [port, cdpPort] = await Promise.all([getPort(), getPort()]);
const profile = await mkdtemp(join(tmpdir(), 'apigo-ui-cdp-'));
const chrome = process.env.CHROME_PATH || '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
const server = spawn(process.execPath, [join(__dirname, 'serve.cjs')], { env: { ...process.env, PORT: String(port) }, stdio: 'inherit' });
const browserProcess = spawn(chrome, [`--headless=new`, `--remote-debugging-port=${cdpPort}`, `--user-data-dir=${profile}`, '--no-first-run', 'about:blank'], { stdio: 'ignore' });
let browser;
try {
await Promise.all([waitFor(`http://127.0.0.1:${port}/ui/ui.test.html`), waitFor(`http://127.0.0.1:${cdpPort}/json/version`)]);
browser = await chromium.connectOverCDP(`http://127.0.0.1:${cdpPort}`);
const context = browser.contexts()[0];
for (const pagePath of pages) {
const page = await context.newPage();
const errors = [];
page.on('pageerror', error => errors.push(error.message));
await page.goto(`http://127.0.0.1:${port}/ui/${pagePath}`, { waitUntil: 'networkidle' });
const result = await page.evaluate(() => globalThis.runTest());
await page.close();
if (errors.length || result?.status !== 'passed') throw new Error(`${pagePath}: ${errors.join('\n') || JSON.stringify(result)}`);
console.log(`Passed ${pagePath}`);
}
} finally {
await browser?.close();
await new Promise(resolve => {
if (browserProcess.exitCode !== null) return resolve();
browserProcess.once('exit', resolve);
browserProcess.kill();
setTimeout(resolve, 2000);
});
server.kill();
await rm(profile, { recursive: true, force: true });
}
})().catch(error => { console.error(error); process.exit(1); });