Files
iptvnator/apps/electron-backend-e2e/src/embedded-mpv-frame-copy-packaged-fixtures.spec.ts
T
4gray 8fdac824fd feat(packaging): ship Linux embedded MPV frame-copy runtime (#1200)
* docs: design Linux frame-copy packaging

* docs: plan Linux frame-copy packaging

* feat(packaging): define Linux frame-copy profiles

* fix(packaging): reject inherited profile names

* feat(embedded-mpv): validate staged Linux runtime

* fix(embedded-mpv): require Linux source packages

* fix(embedded-mpv): harden Linux runtime staging

* feat(embedded-mpv): build LGPL Linux runtime

* fix(embedded-mpv): pin Linux runtime inputs

* feat(embedded-mpv): build relocatable Linux helper

* fix(embedded-mpv): require bundled Linux runtime

* fix(embedded-mpv): make Linux runtime portable

* feat(packaging): ship Linux frame-copy artifacts

* fix(embedded-mpv): verify Linux helper linkage

* fix(packaging): enforce Linux frame-copy isolation

* fix(embedded-mpv): pin Linux display data

* docs(embedded-mpv): document Linux frame-copy packaging

* feat(embedded-mpv): probe Linux frame-copy runtime

* test(embedded-mpv): smoke packaged Linux frame-copy

* docs(embedded-mpv): clarify Linux system runtime baseline

* fix(embedded-mpv): harden Linux runtime capability gate

* ci: verify Linux frame-copy packages

* test(embedded-mpv): harden packaged Linux smoke

* test(embedded-mpv): preserve packaged GL mode

* test(packaging): harden Linux package probes

* fix(embedded-mpv): enable private Snap shared memory

* fix(embedded-mpv): sanitize Linux helper environment

* fix(packaging): enforce private Snap memory semantics

* fix(packaging): reject ambiguous Snap memory metadata

* fix(embedded-mpv): prioritize trusted Snap GL

* fix(packaging): reject advanced Snap YAML semantics

* fix(packaging): reject arbitrary Snap YAML aliases

* feat(packaging): ship Linux runtime license notices

* docs(embedded-mpv): document Linux runtime distribution

* fix(packaging): parse Snap trailing comments safely

* fix(release): gate Snap publish on public source release

* fix(packaging): strip VCS metadata from source bundle

* docs(packaging): clarify Linux source release gate

* test(embedded-mpv): smoke missing bundled libmpv

* style(embedded-mpv): format final validation inputs

* fix(e2e): satisfy fixture index signature typing

* fix(ci): declare fontconfig gperf generator

* fix(embedded-mpv): hash runtime cache identities

* fix(packaging): harden Linux frame-copy delivery

* fix(packaging): tighten runtime delivery gates

* fix(ci): decouple Linux runtime matrix

* fix(packaging): harden Linux frame-copy delivery

* fix(packaging): validate Linux frame-copy runtimes

* fix(packaging): scope Snap Electron library checks

* feat(packaging): ship Linux frame-copy runtimes

* fix(packaging): improve Linux runtime smoke diagnostics

* fix(packaging): expose bounded helper probe details

* test(packaging): trace Snap EGL probe failures

* fix(packaging): prefer core22 ABI in Snap helper

* fix(packaging): bound helper probe capture

* fix(packaging): harden Linux frame-copy releases

* fix(packaging): canonicalize libplacebo submodule identity

* fix(packaging): make source archive inspection portable

* fix(packaging): harden Snap release verification
2026-07-18 17:28:22 +02:00

192 lines
6.6 KiB
TypeScript

import assert = require('node:assert/strict');
import { readFileSync } from 'node:fs';
import { join, resolve } from 'node:path';
import { describe, it } from 'node:test';
import { isMeaningfulNativePlaybackSnapshot } from './embedded-mpv-frame-copy-packaged-fixtures';
import './embedded-mpv-frame-copy-packaged-filesystem.tests';
import { resolvePackagedElectronLaunchArgs } from './electron-test-fixtures';
import packagedPlaywrightConfig from '../playwright.packaged.config';
const projectRoot = resolve(__dirname, '..');
describe('packaged Electron launch arguments', () => {
it('keeps WebGL enabled for software rendering while disabling the sandbox only as root', () => {
assert.deepEqual(
resolvePackagedElectronLaunchArgs(() => 1000),
['--ignore-gpu-blocklist']
);
assert.deepEqual(resolvePackagedElectronLaunchArgs(undefined), [
'--ignore-gpu-blocklist',
]);
assert.deepEqual(
resolvePackagedElectronLaunchArgs(() => 0),
['--ignore-gpu-blocklist', '--no-sandbox']
);
});
});
describe('native-view playback proof', () => {
it('requires the loaded URL, a playing or paused state, and positive duration', () => {
const expectedUrl = 'http://127.0.0.1:3210/fixture.y4m';
const baseSnapshot = {
durationSeconds: 2,
status: 'playing',
streamUrl: expectedUrl,
};
assert.equal(
isMeaningfulNativePlaybackSnapshot(baseSnapshot, expectedUrl),
true
);
assert.equal(
isMeaningfulNativePlaybackSnapshot(
{ ...baseSnapshot, status: 'paused' },
`${expectedUrl}#ignored`
),
true
);
assert.equal(
isMeaningfulNativePlaybackSnapshot(
{ ...baseSnapshot, durationSeconds: null },
expectedUrl
),
false
);
assert.equal(
isMeaningfulNativePlaybackSnapshot(
{ ...baseSnapshot, status: 'idle' },
expectedUrl
),
false
);
assert.equal(
isMeaningfulNativePlaybackSnapshot(
{ ...baseSnapshot, streamUrl: `${expectedUrl}?other=1` },
expectedUrl
),
false
);
});
it('loads the fixture and observes playback before disposing the native session', () => {
const source = readFileSync(
join(projectRoot, 'src', 'embedded-mpv-frame-copy-packaged.e2e.ts'),
'utf8'
);
const fallbackStart = source.indexOf('const launchedFallbackApp');
const captureIndex = source.indexOf(
'installEmbeddedMpvSessionCapture',
fallbackStart
);
const loadIndex = source.indexOf(
'loadEmbeddedMpvPlayback',
fallbackStart
);
const proofIndex = source.indexOf(
'isMeaningfulNativePlaybackSnapshot',
fallbackStart
);
const exitCodeIndex = source.indexOf(
'electronApp.process().exitCode',
fallbackStart
);
const disposeIndex = source.indexOf(
'disposeEmbeddedMpvSession',
fallbackStart
);
assert.ok(fallbackStart >= 0);
assert.ok(captureIndex > fallbackStart);
assert.ok(loadIndex > captureIndex);
assert.ok(proofIndex > loadIndex);
assert.ok(exitCodeIndex > proofIndex);
assert.ok(disposeIndex > exitCodeIndex);
});
it('removes the manifest-declared libmpv target and expects the stable missing-library reason', () => {
const source = readFileSync(
join(projectRoot, 'src', 'embedded-mpv-frame-copy-packaged.e2e.ts'),
'utf8'
);
const manifestIdentityIndex = source.indexOf(
'const runtimeIdentity = readPackagedRuntimeIdentity'
);
const guardIndex = source.indexOf(
'createPackagedEntryGuard(',
manifestIdentityIndex
);
const sonameIndex = source.indexOf(
'runtimeIdentity.libmpvSoname',
guardIndex
);
const hideIndex = source.indexOf('.hide()', sonameIndex);
const fallbackStart = source.indexOf(
'const launchedFallbackApp',
hideIndex
);
const missingReasonIndex = source.indexOf(
"frameCopyUnavailableReason: 'runtime-library-missing'",
fallbackStart
);
assert.ok(manifestIdentityIndex >= 0);
assert.ok(guardIndex > manifestIdentityIndex);
assert.ok(sonameIndex > guardIndex);
assert.ok(hideIndex > sonameIndex);
assert.ok(fallbackStart > hideIndex);
assert.ok(missingReasonIndex > fallbackStart);
assert.doesNotMatch(source, /createRuntimeManifestGuard/);
assert.doesNotMatch(source, /runtimeManifest\.hide/);
});
});
describe('dedicated packaged smoke target', () => {
it('inherits the GL mode from the workflow environment', () => {
const source = readFileSync(
join(projectRoot, 'src', 'embedded-mpv-frame-copy-packaged.e2e.ts'),
'utf8'
);
assert.doesNotMatch(source, /LIBGL_ALWAYS_SOFTWARE\s*:/);
});
it('does not build the backend or start portal mock servers', () => {
const project = JSON.parse(
readFileSync(join(projectRoot, 'project.json'), 'utf8')
) as {
targets?: Record<
string,
{
cache?: boolean;
dependsOn?: unknown;
options?: { command?: string };
}
>;
};
const target = project.targets?.['packaged-frame-copy-smoke'];
const packagedConfig = readFileSync(
join(projectRoot, 'playwright.packaged.config.ts'),
'utf8'
);
if (!target) {
throw new Error('The packaged frame-copy smoke target is missing.');
}
assert.equal(target.cache, false);
assert.deepEqual(target.dependsOn, [
'test-packaged-frame-copy-fixtures',
]);
assert.match(
target.options?.command ?? '',
/playwright\.packaged\.config\.ts/
);
assert.match(
target.options?.command ?? '',
/embedded-mpv-frame-copy-packaged\.e2e\.ts/
);
assert.match(packagedConfig, /timeout:\s*120000/);
assert.match(packagedConfig, /webServer:\s*\[\]/);
assert.deepEqual(packagedPlaywrightConfig.webServer, []);
});
});