Assessor_2.0/tests/maester-reader-browser-chec...

55 lines
4.5 KiB
JavaScript

// 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 {FindingReader} from './src/features/finding-reader/FindingReader';
const fields=[['Source Rule ID','MT.1024'],['Title','Synthetic Maester recommendation check'],['Result','Failed'],['TestScript','$Synthetic = Get-Synthetic'],['HelpUrl','https://maester.dev/docs/tests/MT.1024/']].map(([label,value],index)=>({label,value,index}));
const record={id:'synthetic',index:0,title:'Synthetic Maester recommendation check',fields,filled:fields,meta:[]};
const noop=()=>{};
const description='Synthetic introduction. | Application permission | Path type | Known shortest path | |---|---|---| | <a href="https://example.invalid/read">Synthetic.Read.All</a> | Indirect | First explanation.<br>Note: retain this complete explanation. | | Synthetic.Write.All | Direct | Last explanation. |';
fields.push({label:'Description',value:description,index:fields.length});
createRoot(document.getElementById('root')).render(<FindingReader record={record} title={record.title} linkedSheets={[]} resultReferences={[]} search="" position={0} recordCount={1} toolId="maester" onPrevious={noop} onNext={noop} onReview={noop}/>);
`,resolveDir:process.cwd(),loader:'tsx'},plugins:[{name:'synthetic',setup(build){
build.onResolve({filter:/(?:AppProvider|use-assessment-context)$/},args=>({path:args.path,namespace:'fixture'}));
build.onLoad({filter:/.*/,namespace:'fixture'},args=>({contents:args.path.endsWith('AppProvider')?'export const useOptionalApp=()=>null;':'export const useAssessmentContext=()=>({status:"disabled"});',loader:'js'}));
}}],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 ?? '<!doctype html><html><head><link rel="stylesheet" href="/stdin.css"></head><body><div id="root"></div><script src="/stdin.js"></script></body></html>');
});
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:1100,height:900}});
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);
const details=page.locator('details').filter({has:page.locator('summary', {hasText:'Test details'})});
const code=details.locator('pre');
assert.equal(await code.isVisible(),false);
assert.equal(await page.locator('.reader-summary > h3').textContent(),'Synthetic Maester recommendation check');
assert.equal(await page.locator('.maester-missing-result').isVisible(),true);
const table=page.locator('.rich-text-table-wrap table');
assert.equal(await table.locator('th').count(),3);
assert.equal(await table.locator('tbody tr').count(),2);
assert.equal(await table.locator('td').first().evaluate(cell=>getComputedStyle(cell).fontSize),'14px');
assert.equal(await table.locator('a').getAttribute('href'),'https://example.invalid/read');
assert.match(await table.textContent(),/Note: retain this complete explanation/);
await details.locator('summary').click();assert.equal(await code.isVisible(),true);
assert.equal(await code.textContent(),'$Synthetic = Get-Synthetic');
await details.locator('summary').click();assert.equal(await code.isVisible(),false);
await page.screenshot({path:`.maester-${theme}.png`});
}
console.log('Maester disclosure and heading verified in both themes');
} finally {await browser?.close();await new Promise(resolve=>server.close(resolve));}