test(benchmarks): fix post-login wait, allow V8 flag injection

Sign-in redirects client-side, so page.waitForURL never reached its
implicit "load" state and every run failed after the restore step even
though authentication had succeeded. Poll window.location instead.

STRESS_NODE_OPTIONS injects NODE_OPTIONS directly, which is what makes
the V8 heap cap attributable: the merge-base run.sh does not read
HOMARR_MAX_OLD_SPACE_SIZE, so the cap can only be A/B'd against that
image by passing the flag in.
This commit is contained in:
Thomas Camlong committed 2026-08-09 00:44:50 +02:00
1 parent 0d19968131
commit 6363d96a1b
1 file changed
+18 -2
+18 -2
View File
@@ -39,6 +39,7 @@ const backupZip = path.resolve(requireEnv("STRESS_BACKUP_ZIP").replace(/^~/, os.
const label = process.env.STRESS_LABEL ?? image.replace(/[^a-z0-9]+/gi, "-");
const memoryLimit = process.env.STRESS_MEMORY_LIMIT ?? "2g";
const heapMb = process.env.STRESS_HEAP_MB ?? "";
const nodeOptions = process.env.STRESS_NODE_OPTIONS ?? "";
const navIterations = Number(process.env.STRESS_NAV_ITERATIONS ?? 6);
const soakMs = Number(process.env.STRESS_SOAK_MS ?? 120_000);
const soakIntervalMs = Number(process.env.STRESS_SOAK_INTERVAL_MS ?? 20_000);
@@ -151,7 +152,11 @@ const loginAsync = async (page: Page, baseUrl: string) => {
await page.getByLabel("Username").fill(username);
await page.locator("#password").fill(password);
await page.locator("css=button[type='submit']").click();
await page.waitForURL((url) => !url.pathname.includes("/auth/login"), { timeout: 60_000 });
// Poll location instead of page.waitForURL: sign-in redirects client-side, so
// waitForURL's implicit "load" state may never be reached for that navigation.
await page.waitForFunction(() => !window.location.pathname.includes("/auth/login"), undefined, {
timeout: 60_000,
});
log(`signed in as ${username}`);
};
@@ -223,6 +228,9 @@ const main = async () => {
"LOG_LEVEL=warn",
];
if (heapMb) runArgs.push("-e", `HOMARR_MAX_OLD_SPACE_SIZE=${heapMb}`);
// Escape hatch for A/B-ing V8 flags against an image whose run.sh does not read
// HOMARR_MAX_OLD_SPACE_SIZE (e.g. measuring the heap cap against an older image).
if (nodeOptions) runArgs.push("-e", `NODE_OPTIONS=${nodeOptions}`);
runArgs.push(image);
await execFileAsync("docker", runArgs);
@@ -295,7 +303,15 @@ const main = async () => {
imageSizeBytes: Number(
(await execFileAsync("docker", ["image", "inspect", image, "--format", "{{.Size}}"])).stdout.trim(),
),
config: { memoryLimit, heapMb: heapMb || null, navIterations, soakMs, soakIntervalMs, boardName },
config: {
memoryLimit,
heapMb: heapMb || null,
nodeOptions: nodeOptions || null,
navIterations,
soakMs,
soakIntervalMs,
boardName,
},
// Recorded so an A/B pair can be rejected if the two runs rendered
// different amounts of the board (e.g. more widgets errored on one side).
board: boardOutcome,