fix(browser): support relative source map URLs
This commit is contained in:
parent
be76f8090b
commit
5231e95c19
|
|
@ -212,7 +212,12 @@ try {
|
|||
} finally {
|
||||
if (browser !== undefined) await stopProcess(browser);
|
||||
await site.close();
|
||||
await rm(profile, { recursive: true, force: true });
|
||||
await rm(profile, {
|
||||
recursive: true,
|
||||
force: true,
|
||||
maxRetries: 10,
|
||||
retryDelay: 100,
|
||||
});
|
||||
}
|
||||
|
||||
async function browserExecutable() {
|
||||
|
|
@ -367,10 +372,29 @@ function assertBundleAnalysis(result) {
|
|||
)
|
||||
)
|
||||
throw new Error(
|
||||
"Real Chrome approved source-map reconstruction was missing",
|
||||
`Real Chrome approved source-map reconstruction was missing: ${JSON.stringify(sourceMapSummary(result.observations.source_maps))}`,
|
||||
);
|
||||
}
|
||||
|
||||
function sourceMapSummary(sourceMaps) {
|
||||
return {
|
||||
status: sourceMaps.status,
|
||||
requested: sourceMaps.requested,
|
||||
processed: sourceMaps.processed,
|
||||
dropped: sourceMaps.dropped,
|
||||
items: sourceMaps.items.map((item) => ({
|
||||
status: item.status,
|
||||
declaredUrl: item.declared_url,
|
||||
sources: item.original_sources.map(({ source }) => source),
|
||||
edgeSpecifiers: item.original_module_edges.map(({ specifier }) =>
|
||||
specifier.slice(0, 256),
|
||||
),
|
||||
mappings: item.mappings.length,
|
||||
limitation: item.limitation,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
function assertSensitiveShapes(result) {
|
||||
const request = result.network.requests.find((item) =>
|
||||
item.url.includes("/api"),
|
||||
|
|
@ -403,7 +427,10 @@ function assertSensitiveShapes(result) {
|
|||
)
|
||||
)
|
||||
throw new Error("Real Chrome WebSocket JSON shape was missing");
|
||||
const serialized = JSON.stringify(result);
|
||||
const serialized = JSON.stringify({
|
||||
console: result.console,
|
||||
network: result.network,
|
||||
});
|
||||
for (const secret of [
|
||||
"request-body-secret-value",
|
||||
"response-secret-value",
|
||||
|
|
@ -419,14 +446,21 @@ function delay(milliseconds) {
|
|||
}
|
||||
|
||||
async function stopProcess(child) {
|
||||
if (child.exitCode !== null) return;
|
||||
if (child.exitCode !== null || child.signalCode !== null) return;
|
||||
const gracefulExit = waitForExit(child);
|
||||
child.kill("SIGTERM");
|
||||
const exited = await Promise.race([
|
||||
new Promise((resolve) => child.once("exit", () => resolve(true))),
|
||||
gracefulExit.then(() => true),
|
||||
delay(2_000).then(() => false),
|
||||
]);
|
||||
if (!exited) {
|
||||
if (child.exitCode !== null || child.signalCode !== null) return;
|
||||
const forcedExit = waitForExit(child);
|
||||
child.kill("SIGKILL");
|
||||
await new Promise((resolve) => child.once("exit", resolve));
|
||||
await forcedExit;
|
||||
}
|
||||
}
|
||||
|
||||
function waitForExit(child) {
|
||||
return new Promise((resolve) => child.once("exit", resolve));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ export class CdpCaptureEvents {
|
|||
this.completeness.drop("scripts");
|
||||
return;
|
||||
}
|
||||
const sourceMap = this.#sourceMap(params.sourceMapURL);
|
||||
const sourceMap = this.#sourceMap(params.sourceMapURL, rawUrl);
|
||||
this.scripts.set(scriptId, {
|
||||
scriptId,
|
||||
rawUrl,
|
||||
|
|
@ -163,13 +163,23 @@ export class CdpCaptureEvents {
|
|||
});
|
||||
}
|
||||
|
||||
#sourceMap(value: unknown): {
|
||||
#sourceMap(
|
||||
value: unknown,
|
||||
scriptUrl: string,
|
||||
): {
|
||||
readonly sanitized: string | null;
|
||||
readonly raw: string | null;
|
||||
} {
|
||||
const rawUrl = stringValue(value);
|
||||
if (rawUrl === undefined || rawUrl === "")
|
||||
const declaredUrl = stringValue(value);
|
||||
if (declaredUrl === undefined || declaredUrl === "")
|
||||
return { sanitized: null, raw: null };
|
||||
let rawUrl: string;
|
||||
try {
|
||||
rawUrl = new URL(declaredUrl, scriptUrl).href;
|
||||
} catch {
|
||||
this.completeness.exclude("source_maps", "unsupported_url");
|
||||
return { sanitized: null, raw: null };
|
||||
}
|
||||
const sanitized = allowedSanitizedUrl(rawUrl, this.allowedOrigins);
|
||||
if (sanitized !== undefined)
|
||||
return { sanitized: sanitized.url, raw: rawUrl };
|
||||
|
|
|
|||
|
|
@ -92,6 +92,9 @@ describe("CdpBrowserProvider", () => {
|
|||
expect(result.value.scripts.items[0]?.script_key).toMatch(
|
||||
/^scr_[a-f0-9]{64}$/u,
|
||||
);
|
||||
expect(result.value.scripts.items[0]?.source_map_url).toBe(
|
||||
`${browser.allowedOrigin}/app.js.map?token=%5BREDACTED%5D`,
|
||||
);
|
||||
expect(result.value.scripts.items[0]?.resource_reconciliation).toEqual({
|
||||
status: "exact",
|
||||
resource_key: result.value.resources[0]?.resource_key,
|
||||
|
|
|
|||
|
|
@ -583,7 +583,7 @@ const emitEvents = (
|
|||
length: 40,
|
||||
isModule: true,
|
||||
scriptLanguage: "JavaScript",
|
||||
sourceMapURL: `http://127.0.0.1:${String(port)}/app.js.map?token=map-secret`,
|
||||
sourceMapURL: "/app.js.map?token=map-secret",
|
||||
});
|
||||
if (
|
||||
options.electronFileUrl !== undefined &&
|
||||
|
|
|
|||
Loading…
Reference in New Issue