// Registry tarballs for specs that install real packages, served from // tests/fixtures/tarballs/ (gitignored) and fetched from registry.npmjs.org // only on a miss. A tarball URL never changes content and the kernel checks every one // against its lockfile integrity, so the cached copy is the bytes the network would // send; after one run the suite installs offline. TARBALLS_OFFLINE=1 fails a miss, and // any other request that leaves localhost, which proves a spec needs no network. import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; import type { BrowserContext } from "@playwright/test"; const CACHE = fileURLToPath(new URL("fixtures/tarballs", import.meta.url)); const CORS = { "access-control-allow-origin": "*" }; const cachePath = (url: string): string => join(CACHE, decodeURIComponent(new URL(url).pathname)); function store(file: string, body: Buffer): void { mkdirSync(dirname(file), { recursive: true }); // Parallel workers may fetch the same tarball: write aside, then rename into place. const partial = `${file}.${process.pid}.partial`; writeFileSync(partial, body); renameSync(partial, file); } /** One tarball's bytes for a spec that reads a package outside the browser. */ export async function tarball(url: string): Promise { const file = cachePath(url); if (!existsSync(file)) { if (process.env.TARBALLS_OFFLINE === "1") throw new Error(`${url} is not cached`); const res = await fetch(url); if (!res.ok) throw new Error(`${url}: ${res.status}`); store(file, Buffer.from(await res.arrayBuffer())); } return readFileSync(file); } export async function cacheTarballs(context: BrowserContext): Promise { // Registered first, so every other route (a spec's own registry answers) runs before it. if (process.env.TARBALLS_OFFLINE === "1") { await context.route((url) => url.hostname !== "localhost" && url.hostname !== "127.0.0.1", (route) => route.abort("internetdisconnected")); } await context.route(/^https:\/\/registry\.npmjs\.org\/.+\/-\/[^/]+\.tgz$/, async (route) => { const req = route.request(); if (req.method() !== "GET") return route.fallback(); const file = cachePath(req.url()); if (!existsSync(file)) { if (process.env.TARBALLS_OFFLINE === "1") return route.abort("internetdisconnected"); const res = await route.fetch(); if (res.status() !== 200) return route.fulfill({ response: res }); store(file, await res.body()); } return route.fulfill({ status: 200, headers: CORS, contentType: "application/octet-stream", body: readFileSync(file) }); }); }