mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 14:50:02 +00:00
fix(cli): validate navigation timeout honors --timeout, hints on CDN scripts (#1929)
`validate` navigated the page with a hardcoded 10s timeout that ignored the --timeout option. A composition that loads GSAP (or any library) from a CDN <script> in <head> blocks `domcontentloaded` until that script finishes downloading; on a slow network that exceeds 10s and validate fails with an opaque "Navigation timeout of 10000ms exceeded" — even though the full render (much larger budget) rides it out fine, and even though --timeout (the documented "wait longer for slow loads" knob) had no effect on navigation. The only recourse was to change the composition (vendor the script locally). Reported precisely, with the exact error and the observation that render's 60s budget masks it while validate's 10s trips. Fix: - resolveNavigationTimeoutMs(optTimeout) = max(10s floor, --timeout), so --timeout now also extends the navigation budget. Default behavior is unchanged: the default --timeout (3000) stays clamped to the 10s floor. - navigationTimeoutHint() replaces Puppeteer's opaque timeout error with an actionable message naming the likely cause (a blocking CDN <script>) and the two fixes (vendor locally / raise --timeout). Any non-timeout error is rethrown unchanged. - --timeout help text updated to note it also governs navigation. Both helpers are pure and exported; validateInBrowser wires them around the single page.goto. No behavior change for compositions that navigate within 10s. Test: resolveNavigationTimeoutMs (floor kept for unset/small/zero, raised past the floor) and navigationTimeoutHint (rewrites a nav-timeout error with CDN + --timeout guidance; returns null for other errors so the caller rethrows as-is). validate suite 14 tests pass.
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
extractCompositionErrorsFromLint,
|
||||
navigationTimeoutHint,
|
||||
raceMediaReady,
|
||||
resolveNavigationTimeoutMs,
|
||||
shouldIgnoreRequestFailure,
|
||||
} from "./validate.js";
|
||||
import type { ProjectLintResult } from "../utils/lintProject.js";
|
||||
@@ -192,3 +194,39 @@ describe("extractCompositionErrorsFromLint", () => {
|
||||
expect(errors.map((e) => e.text)).toEqual(["scene-a is empty", "scene-b is empty"]);
|
||||
});
|
||||
});
|
||||
|
||||
// Regression: `validate` used a hardcoded 10s page-navigation timeout that
|
||||
// ignored --timeout, so a composition loading GSAP from a CDN <script> (which
|
||||
// blocks domcontentloaded) failed with an opaque "Navigation timeout of 10000ms"
|
||||
// even though the full render's larger budget rode it out — with no knob to
|
||||
// extend it. resolveNavigationTimeoutMs makes --timeout raise the nav budget
|
||||
// (never below the 10s floor); navigationTimeoutHint replaces the opaque error.
|
||||
describe("resolveNavigationTimeoutMs", () => {
|
||||
it("keeps the 10s floor when --timeout is unset or smaller", () => {
|
||||
expect(resolveNavigationTimeoutMs(undefined)).toBe(10000);
|
||||
expect(resolveNavigationTimeoutMs(3000)).toBe(10000); // the default --timeout
|
||||
expect(resolveNavigationTimeoutMs(0)).toBe(10000);
|
||||
});
|
||||
|
||||
it("raises the navigation budget to --timeout when it exceeds the floor", () => {
|
||||
expect(resolveNavigationTimeoutMs(30000)).toBe(30000);
|
||||
});
|
||||
});
|
||||
|
||||
describe("navigationTimeoutHint", () => {
|
||||
it("replaces a Puppeteer navigation-timeout error with an actionable CDN/--timeout hint", () => {
|
||||
const hinted = navigationTimeoutHint(
|
||||
new Error("Navigation timeout of 10000 ms exceeded"),
|
||||
10000,
|
||||
);
|
||||
expect(hinted).toBeInstanceOf(Error);
|
||||
expect(hinted?.message).toContain("10000ms");
|
||||
expect(hinted?.message).toContain("CDN");
|
||||
expect(hinted?.message).toContain("--timeout");
|
||||
});
|
||||
|
||||
it("returns null for any non-navigation-timeout error so the caller rethrows it as-is", () => {
|
||||
expect(navigationTimeoutHint(new Error("net::ERR_CONNECTION_REFUSED"), 10000)).toBeNull();
|
||||
expect(navigationTimeoutHint("some string failure", 10000)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user