61 lines
4.2 KiB
JavaScript
61 lines
4.2 KiB
JavaScript
const {chromium}=require(process.env.PLAYWRIGHT_MODULE || 'playwright-core');
|
|
const fs=require('fs');
|
|
const assert=require('assert/strict');
|
|
(async()=>{
|
|
const browser=await chromium.launch({headless:true,executablePath:process.env.CHROMIUM_BIN});
|
|
try {
|
|
const page=await browser.newPage({viewport:{width:1440,height:1000}});
|
|
const errors=[];page.on('pageerror',e=>errors.push(String(e)));
|
|
const {execFileSync}=require('child_process');
|
|
const data=JSON.parse(execFileSync(process.env.PYTHON_BIN || 'python3',['-c',`
|
|
import json,sys
|
|
sys.path.insert(0,${JSON.stringify(__dirname)})
|
|
import workflow,trigger
|
|
data={'cards':[
|
|
{'id':'ready','title':'Implement the acceptance criteria','source':'intent','phase':'geplant'},
|
|
{'id':'blocked','title':'Repair publication before continuing','source':'intent','phase':'in_umsetzung','last_run_status':'publish_failed','failure_stage':'publication','failure_detail':'Push rejected; worktree retained.'},
|
|
{'id':'legacy','title':'Check the historical deployment','source':'intent','phase':'deployed','review_report':'docs/review/legacy.md'},
|
|
{'id':'parent','title':'Complete the family','source':'intent','phase':'wartet_auf_kinder'},
|
|
{'id':'child','title':'Answer the child question','source':'intent','phase':'inspector_rueckfrage','parent_id':'parent','clarification_question':'Which acceptance criterion?'},
|
|
{'id':'archive','title':'Archived goal','source':'intent','phase':'archiviert'},
|
|
{'id':'done','title':'Deployed goal','source':'intent','phase':'deployed','deployment_status':'deployed','deployed_commit_hash':'a'*40,'activated_system':'/nix/store/verified-system'}
|
|
]}
|
|
for card in data['cards']:
|
|
children=[c for c in data['cards'] if c.get('parent_id')==card['id']]
|
|
card['display']=workflow.presentation(card,children)
|
|
card['available_actions']=trigger.available_actions(card['id'],card['source'],card)
|
|
print(json.dumps(data))
|
|
`],{encoding:'utf8'}));
|
|
let offline=false;
|
|
await page.route('**/*',route=>{
|
|
const url=new URL(route.request().url());
|
|
assert.equal(route.request().method(),'GET','Browser test must not mutate live state');
|
|
if(url.pathname==='/')return route.fulfill({contentType:'text/html',body:fs.readFileSync(require('path').join(__dirname,'board.html'),'utf8')});
|
|
if(url.pathname==='/api/board')return offline?route.abort():route.fulfill({json:data});
|
|
return route.fulfill({json:{content:'Fixture report: verified local browser test.',runs:[]}});
|
|
});
|
|
await page.goto('http://board.test/');await page.waitForSelector('.card');
|
|
assert.equal(await page.locator('#settings-dialog').isVisible(),false);
|
|
assert.equal(await page.locator('.column[data-lifecycle=archived]').count(),0);
|
|
await page.screenshot({path:'/tmp/intent-board-candidate-desktop.png'});
|
|
await page.locator('[data-action=details]').first().click();
|
|
await page.getByRole('button',{name:'Evidence',exact:true}).click();
|
|
await page.screenshot({path:'/tmp/intent-board-candidate-evidence.png'});
|
|
await page.keyboard.press('Escape');
|
|
await page.locator('#view').selectOption('archived');
|
|
assert.ok(await page.locator('.card').count()>0);
|
|
await page.locator('#search').fill('no-match-xyz');assert.equal(await page.locator('.card').count(),0);
|
|
await page.locator('#search').fill('');await page.locator('#view').selectOption('all');
|
|
const first=page.locator('[data-action=details]').first();await first.focus();
|
|
await page.evaluate(()=>render(true));
|
|
assert.equal(await page.evaluate(()=>document.activeElement.dataset.action),'details');
|
|
await page.setViewportSize({width:390,height:844});await page.emulateMedia({colorScheme:'dark'});
|
|
const dimensions=await page.evaluate(()=>({viewport:innerWidth,width:document.documentElement.scrollWidth}));
|
|
assert.ok(dimensions.width<=dimensions.viewport,JSON.stringify(dimensions));
|
|
await page.screenshot({path:'/tmp/intent-board-candidate-mobile.png'});
|
|
offline=true;await page.evaluate(()=>render(true));
|
|
assert.match(await page.locator('#connection').innerText(),/unavailable/);
|
|
assert.ok(await page.locator('.card').count()>0);assert.deepEqual(errors,[]);
|
|
console.log(JSON.stringify({passed:true,dimensions,errors,screenshots:'/tmp/intent-board-candidate-*.png'}));
|
|
} finally {await browser.close();}
|
|
})().catch(error=>{console.error(error);process.exitCode=1;});
|