Files
iptvnator/apps/electron-backend-e2e/src/performance/journey-renderer-gate-client.spec.ts
T
4grayandClaude Opus 5.5 37ee8813a7 fix(electron): show the main window once its document has loaded; enforce J1 IPC and mutation counters
Re-lands #1788, which merged into #1782's branch after #1782 had already
reached master, so none of it is on master.

The hidden main window was shown on ready-to-show only. On Linux under
X11, when the startup scripts run before the window's first frame, the
next frame comes about a second later: nothing is on screen and the
splash's requestAnimationFrame waits, so J1's first card came ~940 ms
after load instead of ~480 ms in most runner launches (18 bridge calls /
1,031-1,033 DOM mutations instead of 15 / 558).

The window is now shown at ready-to-show or the main frame's
did-finish-load, whichever comes first, with the splash colour as its
background so showing before the first paint does not flash. The journey
gate keeps the app's did-finish-load listeners away from its about:blank
detour, as it already does for ready-to-show.

Three dispatched runs on this branch (37192092882, 37192097790,
37192103151) read 15 calls and 558 mutations in all 18 iterations,
stable: true. Both become baselines (slack 0), and the Performance
journeys job checks them with check-journey-ratchet.mjs --only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 22:56:10 +02:00

64 lines
1.7 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
assertJourneyRendererGate,
JOURNEY_RENDERER_GATE_KEY,
type JourneyRendererGateState,
} from '../journeys/journey-renderer-gate-client';
function gate(
overrides: Partial<JourneyRendererGateState> = {}
): JourneyRendererGateState {
return {
blankLoadedEpochMs: 1_050,
errors: [],
gatedEpochMs: 1_020,
didFinishLoadHeldOnBlank: 1,
gatedMethod: 'loadFile',
passThroughLoads: 0,
readyToShowHeldOnBlank: 1,
releasedEpochMs: 1_150,
timedOut: false,
...overrides,
};
}
test('the client and the hook agree on the global key', () => {
assert.equal(JOURNEY_RENDERER_GATE_KEY, '__iptvnatorJourneyGate');
});
test('accepts a gate that held the load until the test released it', () => {
assert.equal(
assertJourneyRendererGate(gate(), 1_200).releasedEpochMs,
1_150
);
});
test('rejects gates that cannot prove the probe preceded the document', () => {
assert.throws(
() => assertJourneyRendererGate(gate({ timedOut: true }), 1_200),
/timed-out/
);
assert.throws(
() =>
assertJourneyRendererGate(
gate({ errors: ['blank-failed'] }),
1_200
),
/errors: blank-failed/
);
assert.throws(
() => assertJourneyRendererGate(gate({ releasedEpochMs: null }), 1_200),
/incomplete/
);
assert.throws(
() => assertJourneyRendererGate(gate({ passThroughLoads: 1 }), 1_200),
/extra-loads-1/
);
assert.throws(
() => assertJourneyRendererGate(gate(), 1_100),
/probe-before-release/
);
});