Files
workinf_Blender_Wasm/web/tests/unit/sequencer-final-export.test.mjs
mes123456 0fe8d2bb56
Some checks are pending
M6 deployable RC / quick (push) Waiting to run
M6 deployable RC / chromium (push) Blocked by required conditions
M6 deployable RC / release (push) Blocked by required conditions
Advance M8-M11 parity workflows
2026-08-17 04:37:07 -04:00

133 lines
4.9 KiB
JavaScript

import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
import test from "node:test";
import ts from "typescript";
const root = path.resolve(import.meta.dirname, "../../..");
const sourcePath = path.join(root, "web/protocol/sequencer-export.ts");
const source = fs.readFileSync(sourcePath, "utf8").replace('import type { ErrorCode } from "./error";\n', "");
const transpiled = ts.transpileModule(source, {
compilerOptions: { module: ts.ModuleKind.ES2022, target: ts.ScriptTarget.ES2022 },
fileName: sourcePath,
reportDiagnostics: true,
});
assert.deepEqual(transpiled.diagnostics, []);
const finalExport = await import("data:text/javascript;base64," + Buffer.from(transpiled.outputText).toString("base64"));
const golden = JSON.parse(fs.readFileSync(path.join(root, "tests/golden/M11-12/sequencer-final-export.json"), "utf8"));
const request = (overrides = {}) => ({
schemaVersion: 1,
timelineId: "sequencer:scene:SequencerScene",
timelineRevision: 1,
sourceBlendSha256: golden.sourceBlendSha256,
frameStart: 1,
frameEnd: 250,
fpsNumerator: 24000,
fpsDenominator: 1001,
width: 1920,
height: 1080,
container: "MPEG4",
videoCodec: "H264",
audioCodec: "AAC",
...overrides,
});
test("M11-12 requires the declared server export capability", async () => {
const blocked = await finalExport.routeSequencerFinalExport(request(), {
serverExportAvailable: false,
browserVideoEncoderAvailable: false,
});
assert.deepEqual(blocked, golden.withoutServer);
const routed = await finalExport.routeSequencerFinalExport(request(), {
serverExportAvailable: true,
browserVideoEncoderAvailable: false,
});
assert.deepEqual(routed, golden.withServer);
});
test("M11-12 never treats browser VideoEncoder detection as local final-export support", async () => {
for (const serverExportAvailable of [false, true]) {
const withoutEncoder = await finalExport.routeSequencerFinalExport(request(), {
serverExportAvailable,
browserVideoEncoderAvailable: false,
});
const withEncoder = await finalExport.routeSequencerFinalExport(request(), {
serverExportAvailable,
browserVideoEncoderAvailable: true,
});
assert.equal(withoutEncoder.route, "SERVER_EXPORT");
assert.equal(withEncoder.route, "SERVER_EXPORT");
assert.equal(withoutEncoder.localEncoding, "BLOCKED");
assert.equal(withEncoder.localEncoding, "BLOCKED");
assert.equal(withEncoder.browserVideoEncoderDetected, true);
assert.deepEqual(
{ ...withEncoder, browserVideoEncoderDetected: false },
withoutEncoder,
);
}
});
test("M11-12 hashes settings and source revision into deterministic request identities", async () => {
const baseline = await finalExport.routeSequencerFinalExport(request(), {
serverExportAvailable: true,
browserVideoEncoderAvailable: false,
});
assert.equal(baseline.settingsSha256, golden.settingsSha256);
assert.equal(baseline.requestSha256, golden.requestSha256);
assert.deepEqual(
await finalExport.routeSequencerFinalExport({ ...request(), container: "MPEG4" }, {
serverExportAvailable: true,
browserVideoEncoderAvailable: false,
}),
baseline,
);
const revisionDrift = await finalExport.routeSequencerFinalExport(request({ timelineRevision: 2 }), {
serverExportAvailable: true,
browserVideoEncoderAvailable: false,
});
assert.equal(revisionDrift.settingsSha256, baseline.settingsSha256);
assert.notEqual(revisionDrift.requestSha256, baseline.requestSha256);
const settingsDrift = await finalExport.routeSequencerFinalExport(request({ width: 1280 }), {
serverExportAvailable: true,
browserVideoEncoderAvailable: false,
});
assert.notEqual(settingsDrift.settingsSha256, baseline.settingsSha256);
assert.notEqual(settingsDrift.requestSha256, baseline.requestSha256);
});
test("M11-12 rejects undeclared, malformed, and over-budget export requests", async () => {
await assert.rejects(
finalExport.routeSequencerFinalExport({ ...request(), localEncoding: "READY" }, {
serverExportAvailable: true,
browserVideoEncoderAvailable: true,
}),
{ code: "SEQUENCER_EXPORT_REQUEST_INVALID" },
);
await assert.rejects(
finalExport.routeSequencerFinalExport(request({ container: "WEBM", videoCodec: "H264" }), {
serverExportAvailable: true,
browserVideoEncoderAvailable: true,
}),
{ code: "SEQUENCER_EXPORT_REQUEST_INVALID" },
);
await assert.rejects(
finalExport.routeSequencerFinalExport(request({ frameStart: -1_000_000, frameEnd: 1_000_000 }), {
serverExportAvailable: true,
browserVideoEncoderAvailable: true,
}),
{ code: "SEQUENCER_EXPORT_REQUEST_INVALID" },
);
await assert.rejects(
finalExport.routeSequencerFinalExport(request(), {
serverExportAvailable: true,
browserVideoEncoderAvailable: true,
codecName: "h264",
}),
{ code: "SEQUENCER_EXPORT_REQUEST_INVALID" },
);
});