Checkpoint web parity through Chromium input tasks
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled

This commit is contained in:
mes123456
2026-08-19 10:39:03 -04:00
parent 5a11045ca5
commit 380cbed4ff
634 changed files with 41862 additions and 212 deletions

View File

@@ -0,0 +1,64 @@
import assert from "node:assert/strict";
import crypto from "node:crypto";
import fs from "node:fs";
import http from "node:http";
import path from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
const distRoot = path.join(root, "web/dist");
const reportPath = path.join(root, "tests/golden/M14-01C/webkit-capability-report.json");
const manifestPath = path.join(root, "tests/golden/M14-01C/manifest.json");
const digest = (value) => crypto.createHash("sha256").update(value).digest("hex");
const fileDigest = (file) => digest(fs.readFileSync(file));
const mime = new Map([[".html", "text/html; charset=utf-8"], [".js", "text/javascript; charset=utf-8"], [".css", "text/css; charset=utf-8"], [".json", "application/json"], [".wasm", "application/wasm"]]);
const workerName = fs.readdirSync(path.join(distRoot, "assets")).find((name) => /^storage\.worker-[\w-]+\.js$/u.test(name));
const wasmName = fs.readdirSync(path.join(distRoot, "assets")).find((name) => /^web_engine-[\w-]+\.wasm$/u.test(name));
assert.ok(workerName && wasmName, "production worker/WASM assets are missing");
const server = http.createServer((request, response) => {
const pathname = decodeURIComponent(new URL(request.url ?? "/", "http://127.0.0.1").pathname);
const relative = pathname === "/" ? "index.html" : pathname.replace(/^\//u, "");
const file = path.resolve(distRoot, relative);
if (!file.startsWith(`${distRoot}${path.sep}`) || !fs.existsSync(file) || !fs.statSync(file).isFile()) { response.writeHead(404); response.end("not found"); return; }
response.statusCode = 200;
response.setHeader("Content-Type", mime.get(path.extname(file)) ?? "application/octet-stream");
response.setHeader("Cross-Origin-Opener-Policy", "same-origin");
response.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
response.setHeader("Cross-Origin-Resource-Policy", "same-origin");
response.setHeader("Content-Security-Policy", "default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; worker-src 'self'; connect-src 'self'; font-src 'self'; img-src 'self'; media-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'");
fs.createReadStream(file).pipe(response);
});
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
let browser;
try {
const { webkit } = await import(pathToFileURL(path.join(root, "web/node_modules/playwright/index.mjs")).href);
browser = await webkit.launch({ headless: true });
const context = await browser.newContext();
const page = await context.newPage();
const address = server.address();
assert.ok(address && typeof address === "object");
await page.goto(`http://127.0.0.1:${address.port}/`, { waitUntil: "load" });
const probe = await page.evaluate(async ({ workerPath, wasmPath }) => {
const run = async (name, operation) => { try { return { name, ...await operation() }; } catch (error) { return { name, status: "BLOCKED", code: error instanceof Error ? error.name : "PROBE_FAILED", detail: error instanceof Error ? error.message.slice(0, 200) : String(error) }; } };
const wasm = await run("wasm", async () => { const bytes = await fetch(wasmPath).then((response) => { if (!response.ok) throw new Error(`HTTP_${response.status}`); return response.arrayBuffer(); }); await WebAssembly.compile(bytes); return { status: "PASS", code: "WASM_READY", bytes: bytes.byteLength }; });
const worker = await run("worker", async () => { await new Promise((resolve, reject) => { const value = new Worker(workerPath, { type: "module" }); const timer = setTimeout(() => { value.terminate(); resolve(); }, 500); value.onerror = (event) => { clearTimeout(timer); value.terminate(); reject(new Error(event.message || "WORKER_LOAD_FAILED")); }; }); return { status: "PASS", code: "WORKER_READY" }; });
const opfs = await run("opfs", async () => { if (!navigator.storage || typeof navigator.storage.getDirectory !== "function") return { status: "BLOCKED", code: "OPFS_UNAVAILABLE" }; const directory = await navigator.storage.getDirectory(); const probeDirectory = await directory.getDirectoryHandle("m14-webkit-probe", { create: true }); const handle = await probeDirectory.getFileHandle("probe.bin", { create: true }); const writable = await handle.createWritable(); await writable.write(new Uint8Array([1, 2, 3])); await writable.close(); await probeDirectory.removeEntry("probe.bin"); await directory.removeEntry("m14-webkit-probe"); return { status: "PASS", code: "OPFS_READY" }; });
const indexeddb = await run("indexedDB", async () => { if (!indexedDB) return { status: "BLOCKED", code: "INDEXEDDB_UNAVAILABLE" }; const name = "m14-webkit-probe"; await new Promise((resolve, reject) => { const request = indexedDB.open(name, 1); request.onupgradeneeded = () => request.result.createObjectStore("probe"); request.onsuccess = () => { request.result.close(); resolve(); }; request.onerror = () => reject(request.error ?? new Error("INDEXEDDB_OPEN_FAILED")); }); await new Promise((resolve) => { const request = indexedDB.deleteDatabase(name); request.onsuccess = request.onerror = request.onblocked = () => resolve(); }); return { status: "PASS", code: "INDEXEDDB_READY" }; });
const webgl2 = await run("webgl2", async () => { const canvas = document.createElement("canvas"); const gl = canvas.getContext("webgl2"); if (!gl) return { status: "BLOCKED", code: "WEBGL2_UNAVAILABLE" }; const debug = gl.getExtension("WEBGL_debug_renderer_info"); return { status: "PASS", code: "WEBGL2_READY", renderer: debug ? gl.getParameter(debug.UNMASKED_RENDERER_WEBGL) : "REDACTED" }; });
const webgpu = await run("webgpu", async () => { if (!("gpu" in navigator)) return { status: "BLOCKED", code: "WEBGPU_UNAVAILABLE" }; const adapter = await navigator.gpu.requestAdapter(); if (!adapter) return { status: "BLOCKED", code: "WEBGPU_ADAPTER_UNAVAILABLE" }; return { status: "PASS", code: "WEBGPU_READY", adapter: adapter.info?.description ?? adapter.name ?? "REDACTED" }; });
const offscreen = await run("offscreen", async () => { if (typeof OffscreenCanvas !== "function") return { status: "BLOCKED", code: "OFFSCREEN_UNAVAILABLE" }; const canvas = new OffscreenCanvas(2, 2); return { status: "PASS", code: "OFFSCREEN_READY", context2d: Boolean(canvas.getContext("2d")) }; });
const isolation = { name: "isolation", status: crossOriginIsolated ? "PASS" : "BLOCKED", code: crossOriginIsolated ? "ISOLATION_READY" : "ISOLATION_REQUIRED" };
return { userAgent: navigator.userAgent, platform: navigator.platform, hardwareConcurrency: navigator.hardwareConcurrency, capabilities: [wasm, worker, opfs, indexeddb, webgl2, webgpu, offscreen, isolation] };
}, { workerPath: `/assets/${workerName}`, wasmPath: `/assets/${wasmName}` });
const report = { schemaVersion: 1, task: "M14-01C", operation: "WEBKIT_CAPABILITY_PROBE", runtime: "PLAYWRIGHT_WEBKIT", browser: { version: await browser.version(), executablePath: (await import(pathToFileURL(path.join(root, "web/node_modules/playwright/index.mjs")).href)).webkit.executablePath(), userAgent: probe.userAgent, platform: probe.platform, hardwareConcurrency: probe.hardwareConcurrency }, assets: { worker: { path: `web/dist/assets/${workerName}`, sha256: fileDigest(path.join(distRoot, "assets", workerName)) }, wasm: { path: `web/dist/assets/${wasmName}`, sha256: fileDigest(path.join(distRoot, "assets", wasmName)) } }, capabilities: Object.fromEntries(probe.capabilities.map((item) => [item.name, item])), supportRule: "PASS_ONLY_WHEN_PROBED; BLOCKED_OR_UNAVAILABLE_DOES_NOT_CLAIM_SUPPORT", execution: "DISABLED", nextTask: "M14-01D" };
if (process.env.UPDATE_M14_01C_REPORT === "1") { fs.mkdirSync(path.dirname(reportPath), { recursive: true }); fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`); }
assert.deepEqual(JSON.parse(fs.readFileSync(reportPath, "utf8")), report);
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
assert.deepEqual({ schemaVersion: manifest.schemaVersion, task: manifest.task, parentTask: manifest.parentTask, nextTask: manifest.nextTask }, { schemaVersion: 1, task: "M14-01C", parentTask: "M14-01B", nextTask: "M14-01D" });
for (const artifact of Object.values(manifest.artifacts)) assert.equal(fileDigest(path.join(root, artifact.path)), artifact.sha256, artifact.path);
const summary = probe.capabilities.map((item) => `${item.name}=${item.status}`).join(",");
process.stdout.write(`webkit-capability-ok version=${report.browser.version} ${summary} execution=DISABLED next=${manifest.nextTask}\n`);
} finally {
await browser?.close();
await new Promise((resolve) => server.close(resolve));
}