44 lines
4.2 KiB
JavaScript
44 lines
4.2 KiB
JavaScript
// Synthetic display only; no backend, datastore or running application changes.
|
|
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: { resolveDir: process.cwd(), loader: 'tsx', contents: `${styles}
|
|
import React,{useState} from 'react';import {createRoot} from 'react-dom/client';
|
|
import {DockableFilterPanel} from './src/features/sidebar/DockableFilterPanel';
|
|
function Example(){const [selected,setSelected]=useState([]);return <div style={{width:224}}><DockableFilterPanel groups={[{id:'packages',label:'Work Package',selected,onSelect:value=>setSelected(selected.includes(value)?[]:[value]),values:[
|
|
{value:'a',label:'AP-01',count:6,section:{id:'one',label:'01 · Credential Relay Exposure'},clusterColour:'critical'},
|
|
{value:'b',label:'AP-02',count:2,section:{id:'one',label:'01 · Credential Relay Exposure'},clusterColour:'critical'},
|
|
{value:'c',label:'AP-01',count:999,section:{id:'four',label:'04 · AD Privileged Account Exposure'},clusterColour:'high'},
|
|
{value:'u',label:'Unassigned',count:3}]}]}/></div>};createRoot(document.getElementById('root')).render(<Example/>);` }, jsx:'automatic',bundle:true,write:false,outdir:'synthetic',format:'iife',loader:{'.woff2':'dataurl','.woff':'dataurl','.png':'dataurl','.svg':'dataurl'} });
|
|
const server=createServer((req,res)=>{const file=bundle.outputFiles.find(file=>req.url==='/'+file.path.split(/[\\/]/).at(-1));res.setHeader('Content-Type',file?(req.url.endsWith('.css')?'text/css':'text/javascript'):'text/html');res.end(file?.contents??'<!doctype html><html><head><meta charset="utf-8"><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:'chrome'});
|
|
const page=await browser.newPage({viewport:{width:1000,height:800}});
|
|
await page.goto('http://127.0.0.1:'+server.address().port+'/');
|
|
await page.locator('summary').click();
|
|
for(const theme of ['dark','light']) {
|
|
await page.evaluate(theme=>document.documentElement.dataset.theme=theme,theme);
|
|
const heads=page.locator('.work-package-cluster-head');assert.equal(await heads.count(),2);
|
|
for(const head of await heads.all()) {
|
|
const layout=await head.evaluate(node=>{const text=node.children[0].getBoundingClientRect(),marker=node.children[1].getBoundingClientRect();return {right:marker.left>=text.right,square:marker.width===marker.height,width:marker.width,color:getComputedStyle(node.children[1]).backgroundColor};});
|
|
assert.equal(layout.right,true);assert.equal(layout.square,true);assert.ok(layout.width>0);
|
|
assert.notEqual(layout.color,'rgba(0, 0, 0, 0)');
|
|
}
|
|
assert.equal(await page.locator('.work-filter-value .work-package-cluster-colour').count(),0);
|
|
const rights=await page.locator('.work-filter-value strong').evaluateAll(nodes=>nodes.map(node=>node.getBoundingClientRect().right));
|
|
assert.ok(Math.max(...rights)-Math.min(...rights)<1);
|
|
const row=page.getByRole('button',{name:'01 · Credential Relay Exposure → AP-02: 2',exact:true});
|
|
await row.focus();await page.keyboard.press('Space');assert.equal(await row.getAttribute('aria-pressed'),'true');
|
|
await page.getByRole('button',{name:'Detach filters',exact:true}).click();assert.equal(await row.getAttribute('aria-pressed'),'true');
|
|
await page.getByRole('button',{name:'Dock filters',exact:true}).first().click();
|
|
await row.click();assert.equal(await row.getAttribute('aria-pressed'),'false');
|
|
}
|
|
console.log('Both themes: cluster headers, right-hand colour squares, aligned counts and keyboard selection across docking verified.');
|
|
} finally {await browser?.close();await new Promise(resolve=>server.close(resolve));}
|