Advance M7 workflows and release operations
This commit is contained in:
110
web/tests/e2e/single-thread-unisolated.spec.ts
Normal file
110
web/tests/e2e/single-thread-unisolated.spec.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
import path from "node:path";
|
||||
|
||||
const basicBlend = path.resolve(import.meta.dirname, "../../../tests/files/web/basic_scene.blend");
|
||||
|
||||
test("boots and edits with the single-thread engine without cross-origin isolation", async ({ page }) => {
|
||||
const engineAssetUrls: string[] = [];
|
||||
page.on("request", (request) => {
|
||||
const url = new URL(request.url());
|
||||
if (/web_engine|pthread/i.test(url.pathname)) engineAssetUrls.push(url.pathname);
|
||||
});
|
||||
|
||||
const documentResponse = await page.goto("/");
|
||||
expect(documentResponse).not.toBeNull();
|
||||
const headers = await documentResponse!.allHeaders();
|
||||
expect(headers["cross-origin-opener-policy"]).toBeUndefined();
|
||||
expect(headers["cross-origin-embedder-policy"]).toBeUndefined();
|
||||
expect(headers["cross-origin-resource-policy"]).toBeUndefined();
|
||||
|
||||
const platform = await page.evaluate(async () => {
|
||||
const {
|
||||
detectBrowserCapabilities,
|
||||
gateWasmThreadingCapability,
|
||||
selectWebEngineVariant,
|
||||
} = await import("/src/platform/capabilities.ts");
|
||||
const capabilities = detectBrowserCapabilities();
|
||||
const pthreadGate = gateWasmThreadingCapability(capabilities);
|
||||
const manifest = await fetch("/engine-manifest.json", { cache: "no-store" }).then((response) => response.json()) as {
|
||||
schemaVersion: number;
|
||||
memory?: { shared: boolean };
|
||||
variants?: Array<{
|
||||
id: "single" | "pthread";
|
||||
memory: { shared: boolean };
|
||||
resources: { js: { url: string }; wasm: { url: string } };
|
||||
}>;
|
||||
};
|
||||
const singleMemory = manifest.schemaVersion === 2
|
||||
? manifest.variants?.find((variant) => variant.id === "single")?.memory
|
||||
: manifest.memory;
|
||||
const selection = selectWebEngineVariant(
|
||||
manifest as Parameters<typeof selectWebEngineVariant>[0],
|
||||
"AUTO",
|
||||
capabilities,
|
||||
);
|
||||
if (!selection.selectedVariant) throw new Error("AUTO did not select a single-thread variant");
|
||||
const selected = selection.selectedVariant;
|
||||
const wasmBinary = await fetch(selected.resources.wasm.url, { cache: "no-store" })
|
||||
.then((response) => {
|
||||
if (!response.ok) throw new Error(`single WASM request failed: ${response.status}`);
|
||||
return response.arrayBuffer();
|
||||
});
|
||||
const imported = await import(/* @vite-ignore */ selected.resources.js.url) as {
|
||||
default: (options: { wasmBinary: ArrayBuffer }) => Promise<{
|
||||
HEAPU8: Uint8Array;
|
||||
_web_engine_create(): number;
|
||||
_web_engine_destroy(handle: number): void;
|
||||
_web_engine_get_live_handles(): number;
|
||||
}>;
|
||||
};
|
||||
const module = await imported.default({ wasmBinary });
|
||||
const variantHandle = module._web_engine_create();
|
||||
const variantSharedMemory = typeof SharedArrayBuffer !== "undefined" &&
|
||||
module.HEAPU8.buffer instanceof SharedArrayBuffer;
|
||||
module._web_engine_destroy(variantHandle);
|
||||
return {
|
||||
crossOriginIsolated: capabilities.crossOriginIsolated,
|
||||
sharedArrayBuffer: capabilities.sharedArrayBuffer,
|
||||
worker: capabilities.worker,
|
||||
pthreadGate,
|
||||
autoSelectedVariant: selected.id,
|
||||
variantHandle,
|
||||
variantSharedMemory,
|
||||
variantLiveAfterDestroy: module._web_engine_get_live_handles(),
|
||||
manifestSchemaVersion: manifest.schemaVersion,
|
||||
manifestSharedMemory: singleMemory?.shared,
|
||||
};
|
||||
});
|
||||
|
||||
expect(platform).toMatchObject({
|
||||
crossOriginIsolated: false,
|
||||
sharedArrayBuffer: false,
|
||||
worker: true,
|
||||
autoSelectedVariant: "single",
|
||||
variantSharedMemory: false,
|
||||
variantLiveAfterDestroy: 0,
|
||||
manifestSchemaVersion: 2,
|
||||
manifestSharedMemory: false,
|
||||
pthreadGate: {
|
||||
taskId: "M6-02",
|
||||
capability: "WASM_PTHREAD_ENGINE",
|
||||
status: "BLOCKED",
|
||||
},
|
||||
});
|
||||
expect(platform.variantHandle).toBeGreaterThan(0);
|
||||
expect(platform.pthreadGate.issues.map((issue) => issue.path)).toEqual([
|
||||
"crossOriginIsolated",
|
||||
"sharedArrayBuffer",
|
||||
]);
|
||||
|
||||
await expect(page.getByTestId("engine-status")).toContainText("Engine: ready", { timeout: 30_000 });
|
||||
await expect(page.locator(".status-bar")).toContainText("WASM ABI: ready");
|
||||
expect(engineAssetUrls.some((url) => url.endsWith("/vendor/blender/web_engine.wasm"))).toBe(true);
|
||||
expect(engineAssetUrls.some((url) => url.endsWith("/vendor/blender/single/web_engine.wasm"))).toBe(true);
|
||||
expect(engineAssetUrls.some((url) => /pthread/i.test(url))).toBe(false);
|
||||
|
||||
await page.setInputFiles("[data-testid=blend-file-input]", basicBlend);
|
||||
await expect(page.getByTestId("scene-stats")).toContainText("Objects 3 · Vertices 8 · Faces 6");
|
||||
await page.getByRole("button", { name: "添加立方体" }).click();
|
||||
await expect(page.getByTestId("scene-stats")).toContainText("Objects 4 · Vertices 16 · Faces 18");
|
||||
});
|
||||
Reference in New Issue
Block a user