Files
workinf_Blender_Wasm/web/tests/e2e/sequencer-final-export.spec.ts
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

95 lines
3.6 KiB
TypeScript

import { expect, test } from "@playwright/test";
import fs from "node:fs";
import path from "node:path";
const root = path.resolve(import.meta.dirname, "../../..");
const blend = fs.readFileSync(path.join(root, "tests/files/web/sequencer_scene.blend"));
const golden = JSON.parse(fs.readFileSync(path.join(root, "tests/golden/M11-12/sequencer-final-export.json"), "utf8")) as {
sourceBlendSha256: string;
settingsSha256: string;
requestSha256: string;
};
test("M11-12 routes a real Main timeline to server export even when VideoEncoder exists", async ({ page }) => {
await page.goto("/");
const result = await page.evaluate(async (input) => {
const [{ WebEngineClient }, finalExport] = await Promise.all([
import("/src/engine-client/WebEngineClient.ts"),
import("/src/sequencer/SequencerFinalExport.ts"),
]);
const source = Uint8Array.from(input).buffer;
const sourceBlendSha256 = Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256", source)), (byte) =>
byte.toString(16).padStart(2, "0")).join("");
const client = new WebEngineClient({ timeoutMs: 20_000 });
try {
const opened = await client.openBlend(source);
const timeline = opened.snapshot.scenes.find((scene) => scene.name === "SequencerScene")?.sequencerTimeline;
if (!timeline) throw new Error("Real Sequencer Main timeline is missing");
const request = {
schemaVersion: 1 as const,
timelineId: timeline.id,
timelineRevision: timeline.revision,
sourceBlendSha256,
frameStart: timeline.frameStart,
frameEnd: timeline.frameEnd,
fpsNumerator: timeline.fpsNumerator,
fpsDenominator: timeline.fpsDenominator,
width: 1920,
height: 1080,
container: "MPEG4" as const,
videoCodec: "H264" as const,
audioCodec: "AAC" as const,
};
const withoutServer = await finalExport.routeSequencerFinalExportInBrowser(request, false, {});
const serverWithoutEncoder = await finalExport.routeSequencerFinalExportInBrowser(request, true, {});
const serverWithEncoder = await finalExport.routeSequencerFinalExportInBrowser(
request,
true,
{ VideoEncoder: class TestVideoEncoder {} },
);
const runtime = await finalExport.routeSequencerFinalExportInBrowser(request, true);
return { timeline, sourceBlendSha256, withoutServer, serverWithoutEncoder, serverWithEncoder, runtime };
}
finally {
client.terminate();
}
}, Array.from(blend));
expect(result.timeline).toMatchObject({
id: "sequencer:scene:SequencerScene",
revision: 1,
frameStart: 1,
frameEnd: 250,
fpsNumerator: 24000,
fpsDenominator: 1001,
});
expect(result.sourceBlendSha256).toBe(golden.sourceBlendSha256);
expect(result.withoutServer).toMatchObject({
requestSha256: golden.requestSha256,
settingsSha256: golden.settingsSha256,
route: "SERVER_EXPORT",
status: "BLOCKED",
code: "SEQUENCER_EXPORT_SERVER_UNAVAILABLE",
localEncoding: "BLOCKED",
browserVideoEncoderDetected: false,
});
expect(result.serverWithoutEncoder).toMatchObject({
requestSha256: golden.requestSha256,
settingsSha256: golden.settingsSha256,
route: "SERVER_EXPORT",
status: "SERVER_EXPORT_REQUIRED",
code: null,
localEncoding: "BLOCKED",
browserVideoEncoderDetected: false,
});
expect(result.serverWithEncoder).toMatchObject({
...result.serverWithoutEncoder,
browserVideoEncoderDetected: true,
});
expect(result.runtime).toMatchObject({
route: "SERVER_EXPORT",
status: "SERVER_EXPORT_REQUIRED",
localEncoding: "BLOCKED",
});
});