Files
reverse-engineering-anything/tests/boundary/cli/harBrowserSerializedUrlsCli.test.ts
T
84990f9777 test: remove fixed child-process deadlines from tests
239 literal timeoutMs values on cli.run and processes.run only restated
a guess at host speed. On hosted runners with four workers, cliOutput's
3-second value failed while the command still produced correct output.
Deadlines that are the behavior under test, derived from an operation
budget, or that bound a regression's wait remain.

Co-Authored-By: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-14 13:21:13 +08:00

118 lines
3.9 KiB
TypeScript

import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { expect } from "vitest";
import { historicalHar } from "../../fixtures/historicalHar.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest } from "../../support/cli/cliFixture.js";
/** A HAR whose entries copy the fixture entry with each request URL. */
const harWithRequestUrls = (urls: readonly string[]) => {
const har = historicalHar();
const [entry] = har.log.entries;
if (entry === undefined) throw new Error("Expected a fixture HAR entry");
return {
log: {
...har.log,
entries: urls.map((url) => ({
...entry,
request: { ...entry.request, url },
})),
},
};
};
const writeHar = async (urls: readonly string[]): Promise<string> => {
const path = join(
await createTestTempDirectory("rea-har-request-url-"),
"capture.har",
);
await writeFile(path, JSON.stringify(harWithRequestUrls(urls)));
return path;
};
// Each URL is exactly what a WHATWG URL serializer emits, as browsers record
// and send it; RFC 3986 alone rejects the unescaped characters.
const BROWSER_SERIALIZED = [
"https://fonts.googleapis.com/css?family=Roboto:400,700|Open+Sans",
"https://api.example.test/graphql?variables={%22id%22:1}",
"https://api.example.test/search?q=`x`^[1]&rate=100%",
"https://api.example.test/a|b?q=c\\d",
];
cliTest(
"keeps admitting an RFC 3986 request URL that WHATWG would rewrite",
async ({ cli }) => {
const url = "https://EXAMPLE.test/a";
expect(new URL(url).href).not.toBe(url);
const har = await writeHar([url]);
const inspected = await cli.run({
arguments: ["inspect-web-network-capture", har, "har", "--json"],
});
expect(inspected.exitCode, inspected.stdout + inspected.stderr).toBe(0);
expect(inspected.json).toMatchObject({
normalized_result: { records: [{ reported: { request: { url } } }] },
});
},
);
cliTest(
"inspects and builds HARs whose request URLs are browser serializations",
async ({ cli }) => {
for (const url of BROWSER_SERIALIZED)
expect(new URL(url).href, "fixture must be a WHATWG serialization").toBe(
url,
);
const har = await writeHar(BROWSER_SERIALIZED);
const inspected = await cli.run({
arguments: ["inspect-web-network-capture", har, "har", "--json"],
});
expect(inspected.exitCode, inspected.stdout + inspected.stderr).toBe(0);
expect(inspected.json).toMatchObject({
normalized_result: {
total_records: BROWSER_SERIALIZED.length,
records: BROWSER_SERIALIZED.map((url) => ({
reported: { request: { url } },
})),
},
});
const built = await cli.run({
arguments: ["environment-build", har, "--dry-run", "--json"],
});
expect(built.exitCode, built.stdout + built.stderr).toBe(0);
expect(built.json).toMatchObject({
status: "planned",
capture: { records: BROWSER_SERIALIZED.length, input: "har" },
});
},
);
cliTest.for([
// WHATWG rewrites these spellings, so the recorded text and its reading differ.
{ name: "backslash authority", url: "http:\\\\user:pass@host.test/" },
{ name: "tab", url: "https://host.test/a\tb" },
{ name: "space", url: "https://host.test/a b" },
{ name: "relative reference", url: "/a|b" },
])(
"still rejects a request URL that is neither RFC 3986 nor a WHATWG serialization: $name",
async ({ url }, { cli }) => {
const har = await writeHar([url]);
const result = await cli.run({
arguments: ["inspect-web-network-capture", har, "har", "--json"],
});
expect(result.exitCode).toBe(1);
expect(result.json).toMatchObject({
code: "invalid_request",
details: {
issues: [
{
path: ["capture_path", "/log/entries/0/request/url"],
reason: "invalid_format",
},
],
},
});
},
);