// Synthetic browser acceptance. Run with PLAYWRIGHT_MODULE pointing to Playwright's index.mjs. import assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; import { createServer } from 'node:http'; import { pathToFileURL } from 'node:url'; import { build } from 'esbuild'; const { chromium } = await import(pathToFileURL(process.env.PLAYWRIGHT_MODULE).href); const main = await readFile('src/main.tsx', 'utf8'); const styles = [...main.matchAll(/^import '([^']+\.css)';/gm)].map(([, path]) => `import ${JSON.stringify(path.startsWith('.') ? './src/' + path.slice(2) : path)};`).join('\n'); const bundle=await build({stdin:{contents:`${styles} import React from 'react';import {createRoot} from 'react-dom/client';import {ActivityCenter} from './src/components/ActivityCenter'; import {AssessorApiClient} from './src/api/assessor-api-client';import {clearFinishedActivities,beginActivity} from './src/platform/activity-store'; const pending=[];const api=new AssessorApiClient({fetcher:()=>new Promise(resolve=>pending.push(resolve))}); window.start=()=>{clearFinishedActivities();api.loadAssessmentModel('synthetic').catch(()=>{});api.getAssessmentContext('synthetic', ['synthetic']).catch(()=>{});api.createReportRun('synthetic',{kind:'technical'}).catch(()=>{});api.refreshMitreCatalog().catch(()=>{});const queued=beginActivity('Future Engine','Waiting for worker');queued.queue();window.queued=queued;}; window.finish=()=>{pending.splice(0).forEach((resolve,i)=>resolve(new Response('{}',{status:i===2?500:200})));window.queued.run();window.queued.complete();}; createRoot(document.getElementById('root')).render(<>

Synthetic activity acceptance

); `,resolveDir:process.cwd(),loader:'tsx'},define:{'import.meta.env.DEV':'false'},jsx:'automatic',bundle:true,write:false,outdir:'synthetic',format:'iife',loader:{'.woff2':'dataurl','.woff':'dataurl'}}); const server = createServer((request, response) => { const file = bundle.outputFiles.find(file => request.url === '/' + file.path.split(/[\\/]/).at(-1)); response.setHeader('Content-Type', file ? (request.url.endsWith('.css') ? 'text/css' : 'text/javascript') : 'text/html'); response.end(file?.contents ?? '
'); }); await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)); let browser; try { browser=await chromium.launch({headless:true,channel:'msedge'}); const page=await browser.newPage({viewport:{width:1280,height:900}}); const errors=[];page.on('pageerror',e=>errors.push(e.message)); await page.goto(`http://127.0.0.1:${server.address().port}/`); for(const theme of ['dark','light']) { await page.evaluate(t=>document.documentElement.dataset.theme=t,theme); await page.getByRole('button',{name:'Load synthetic client'}).click(); const center=page.getByRole('complementary',{name:'Application activity'}); assert.ok((await center.textContent()).includes('4 running · 1 waiting')); for(const name of ['Core Engine','Context Engine','Report Engine','Future Engine','Updating MITRE catalog']) assert.ok((await center.textContent()).includes(name)); await page.screenshot({path:`.activity-${theme}.png`}); await page.getByRole('button',{name:'Complete synthetic tasks'}).click(); await page.getByRole('button',{name:'Activity · 1 failed'}).waitFor(); assert.ok((await center.textContent()).includes('Completed')); await page.getByRole('button',{name:'Activity · 1 failed'}).click();assert.equal(await center.locator('ul').count(),0); await page.getByRole('button',{name:'Activity · 1 failed'}).click(); await page.getByRole('button',{name:'Clear finished'}).click();assert.equal(await center.count(),0); } assert.deepEqual(errors,[]);console.log('Activity center: parallel engines, catalog update, queued work, failure and clear verified in both themes'); } finally {await browser?.close();await new Promise(resolve=>server.close(resolve));}