Private
Public Access
58 lines
3.2 KiB
JavaScript
58 lines
3.2 KiB
JavaScript
// Exercise the real status renderer without a browser, network or camera.
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const vm = require('node:vm');
|
|
const html = fs.readFileSync(path.join(__dirname, '../halloween/index.html'), 'utf8');
|
|
const detectionRefresh = html.slice(html.indexOf(' async function refreshDetection() {'), html.indexOf(' function updateDetectionHelp()'));
|
|
const refresh = html.slice(html.indexOf(' async function refresh() {'), html.indexOf(' async function action('));
|
|
|
|
async function render(controller, detection) {
|
|
const nodes = {};
|
|
const context = vm.createContext({
|
|
document: {activeElement: null},
|
|
$: id => nodes[id] || (nodes[id] = {}),
|
|
names: {sanft: 'Sanft'},
|
|
fetch: async () => ({json: async () => ({controller, detection, camera: {ready:true, source:'Test'}})})
|
|
});
|
|
vm.runInContext(refresh, context);
|
|
await vm.runInContext('refresh()', context);
|
|
return nodes;
|
|
}
|
|
|
|
(async () => {
|
|
const controller = {mode:'sanft', phase:'Bereich frei abwarten', cooldown_seconds:0};
|
|
const ready = {enabled:true, ready:true, armed:true, method:'motion_test'};
|
|
let nodes = await render(controller, ready);
|
|
assert.equal(nodes.phase.textContent, 'Bereit (Automatik)', 'Automatic ready does not need manual clear');
|
|
nodes = await render({...controller, phase:'Bereit'}, {...ready, armed:false});
|
|
assert.equal(nodes.phase.textContent, 'Ruhiges Bild abwarten (Automatik)', 'Manual clear cannot claim automatic ready');
|
|
for (const phase of ['Stopp', 'Sperrzeit', 'Sanft (simuliert)']) {
|
|
nodes = await render({...controller, phase}, ready);
|
|
assert.equal(nodes.phase.textContent, phase, 'Preserve actual sequence/stop/cooldown');
|
|
}
|
|
nodes = await render({...controller, mode:'aus'}, ready);
|
|
assert.equal(nodes.phase.textContent, 'Modus ohne Schreckauslösung');
|
|
nodes = await render(controller, {...ready, reset_required:true});
|
|
assert.equal(nodes.phase.textContent, 'Erkennung gesperrt; zurücksetzen');
|
|
nodes = await render(controller, {...ready, enabled:false});
|
|
assert.equal(nodes.phase.textContent, controller.phase, 'Manual mode retains its own clear requirement');
|
|
const motionNodes = {};
|
|
const motionContext = vm.createContext({
|
|
$: id => motionNodes[id] || (motionNodes[id] = {}),
|
|
detectionEpoch:0, performance:{now:() => 0}, people:[], processed:false,
|
|
setTimeout:() => {}, drawDetection:() => {},
|
|
fetch:async () => ({ok:true, json:async () => ({
|
|
status:{...ready, fps:5}, image_base64:null,
|
|
motion:{changed_fraction:.0014, note:'Bewegung in Pfeilrichtung', confirmed_frames:2, moving:true, directed:true}
|
|
})})
|
|
});
|
|
vm.runInContext(detectionRefresh, motionContext);
|
|
await vm.runInContext('refreshDetection()', motionContext);
|
|
assert.equal(motionNodes['motion-details'].hidden, false);
|
|
assert.match(motionNodes['motion-details'].textContent, /0,14 %/);
|
|
assert.match(motionNodes['motion-details'].textContent, /Bewegung in Pfeilrichtung/);
|
|
assert.match(motionNodes['motion-details'].textContent, /Bestätigung 2\/2/);
|
|
console.log('UI status tests passed');
|
|
})().catch(error => {console.error(error); process.exitCode = 1;});
|