Files
pulse-signage/test/player-page-commands-performance.test.js
T
lzstealth 75b5cb5a6b
Publish Docker Image / build-and-push (./build/Dockerfile, git.lzstealth.com/lzstealth/pulse-signage-web, web) (push) Successful in 1m17s
Publish Docker Image / build-and-push (./build/Dockerfile.player, git.lzstealth.com/lzstealth/pulse-signage-player, player) (push) Successful in 32s
Add player keyboard controls and release 2.7.1
2026-08-14 13:50:40 +01:00

131 lines
3.3 KiB
JavaScript

const fs = require('node:fs');
const path = require('node:path');
const vm = require('node:vm');
const test = require('node:test');
const assert = require('node:assert/strict');
function loadCommandsScript(sandbox) {
const commandsPath = path.join(__dirname, '..', 'src', 'player', 'public', 'js', 'player-page-commands.js');
const commandsScript = fs.readFileSync(commandsPath, 'utf8');
vm.runInNewContext(commandsScript, sandbox, { filename: commandsPath });
}
function createSandbox() {
const rafCallbacks = [];
const calls = {
syncRtmpRegions: 0,
initRegion: 0,
playRegionAnimations: 0
};
const app = {
children: [],
firstElementChild: null,
innerHTMLValue: '',
classList: {
contains() {
return false;
}
},
set innerHTML(value) {
this.innerHTMLValue = String(value || '');
this.firstElementChild = this.innerHTMLValue ? { isConnected: true } : null;
},
get innerHTML() {
return this.innerHTMLValue;
},
appendChild(node) {
if (node) {
node.isConnected = true;
this.children.push(node);
this.firstElementChild = this.firstElementChild || node;
}
return node;
},
querySelectorAll() {
return [];
}
};
const sandbox = {
window: null,
Date,
JSON,
Math,
Number,
String,
Boolean,
Array,
Object,
Promise,
setTimeout,
clearTimeout,
console,
requestAnimationFrame(callback) {
rafCallbacks.push(callback);
return rafCallbacks.length;
},
app,
slides: [],
index: 0,
currentPlaylistSignature: 'signature',
currentPlaylistFadeBetweenSlides: false,
currentPlaylistSkipUnavailableRtmp: false,
pendingPlaylistUpdate: null,
slideMarkupCache: Object.create(null),
templateLayoutCache: Object.create(null),
templateRenderPlanCache: Object.create(null),
renderCacheViewportKey: '',
slideTransitionTimer: null,
slideFadeDurationMs: 560,
slideExpiresAt: null,
pausedRemainingMs: null,
timer: null,
lastRenderedSlide: null,
destroyRtmpRegions() {},
syncRtmpRegions() {
calls.syncRtmpRegions += 1;
},
initializeRegionInstances() {
calls.initializeRegionInstances += 1;
},
playRegionAnimations() {
calls.playRegionAnimations += 1;
},
addEventListener() {},
pulsePlayerRegionTypes: {
list() {
return [
{
definition: {
initRegion() {
calls.initRegion += 1;
}
}
}
];
}
},
isThumbnailPreview() {
return false;
}
};
sandbox.window = sandbox;
sandbox.window.requestAnimationFrame = sandbox.requestAnimationFrame;
return { sandbox, calls, rafCallbacks, app };
}
test('renderSlideMarkup runs post-render setup immediately', () => {
const { sandbox, calls, rafCallbacks, app } = createSandbox();
loadCommandsScript(sandbox);
const returned = sandbox.renderSlideMarkup('<div class="slide">visible</div>', false);
assert.equal(app.innerHTMLValue, '<div class="slide">visible</div>');
assert.equal(calls.syncRtmpRegions, 1);
assert.equal(calls.initRegion, 1);
assert.equal(calls.playRegionAnimations, 1);
assert.equal(rafCallbacks.length, 0);
assert.equal(returned, app.firstElementChild);
});