Skip to content

Commit 0844818

Browse files
committed
fix(cli): honor check navigation timeout
1 parent d8d6265 commit 0844818

9 files changed

Lines changed: 54 additions & 7 deletions

File tree

docs/packages/cli.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ Word-level transcripts (whisper output) are grouped into readable caption cues o
542542
| `--snapshots` | Write overview frames (annotated with labeled finding boxes when there are errors) plus `finding-NN-<code>.png` crops |
543543
| `--samples` / `--at` / `--at-transitions` | Control the seek grid (default 9 samples; `--at-transitions` adds tween boundaries) |
544544
| `--tolerance` | Allowed overflow in px before reporting (default 2) |
545-
| `--timeout` | Initial settle budget in ms (default 3000) |
545+
| `--timeout` | Initial render-ready budget in ms; also raises the page-navigation budget above its 10s floor (default 3000) |
546546
| `--no-contrast` | Skip the WCAG audit while iterating |
547547
| `--strict` | Exit non-zero on warnings too (default: only errors) |
548548
| `--caption-zone "<x0=..;y0=..;x1=..;y1=..>"` | Opt-in band gate: flags content whose center sits inside the fractional band (optional `severity`, `seek`) |

packages/cli/src/capture/captureCompositionFrame.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ export interface SettledCompositionPage {
6161
}
6262

6363
export interface OpenSettledCompositionPageOptions {
64+
// Separate from the post-navigation render-ready budget. Diagnostic callers
65+
// without their own navigation knob keep the historical 10-second minimum.
66+
navigationTimeoutMs?: number;
6467
renderReadyTimeoutMs: number;
6568
renderReadyWarningSuffix: string;
6669
// Screenshot paths take the engine's software-GPU default; validate/check
@@ -182,7 +185,7 @@ export async function openSettledCompositionPage(
182185
await options.beforeNavigate?.(page);
183186
await page.goto(url, {
184187
waitUntil: "domcontentloaded",
185-
timeout: resolveDiagnosticNavigationTimeoutMs(),
188+
timeout: resolveDiagnosticNavigationTimeoutMs(process.env, options.navigationTimeoutMs),
186189
});
187190
const renderReadyTimedOut = !(await waitForCompositionSettle(page, options));
188191
return { browser: chromeBrowser, page, renderReadyTimedOut };

packages/cli/src/commands/check.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ export function createCheckCommand(
8686
},
8787
timeout: {
8888
type: "string",
89-
description: "Ms to wait for scripts and media to settle initially (default: 3000)",
89+
description:
90+
"Initial render-ready timeout in ms; also sets the navigation minimum (10s floor, default: 3000)",
9091
default: "3000",
9192
},
9293
contrast: {

packages/cli/src/utils/checkBrowser.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,28 @@ it("carries raw browser geometry through the page driver and pipeline", async ()
155155
expect(mocks.serverClose).toHaveBeenCalledOnce();
156156
});
157157

158+
it("uses check --timeout for both navigation and render-ready settling", async () => {
159+
mountCanvasFixture();
160+
const page = fakePage();
161+
installSessionMock(page);
162+
163+
await runBrowserCheck(
164+
PROJECT,
165+
{ ...DEFAULT_CHECK_OPTIONS, samples: 1, contrast: false, timeout: 30_000 },
166+
{ kind: "none" },
167+
runAuditGrid,
168+
);
169+
170+
expect(openSettledCompositionPage).toHaveBeenCalledWith(
171+
"<html></html>",
172+
"http://127.0.0.1:3000",
173+
expect.objectContaining({
174+
navigationTimeoutMs: 30_000,
175+
renderReadyTimeoutMs: 30_000,
176+
}),
177+
);
178+
});
179+
158180
it("round-trips the browser script's raw contrast candidates back into finish", async () => {
159181
// The U2 regression class: Node parses prepare's candidates for reporting,
160182
// but must hand the UNTOUCHED objects back to __contrastAuditFinish — the

packages/cli/src/utils/checkBrowser.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export async function runBrowserCheck(
165165
try {
166166
const launchSettleStart = Date.now();
167167
const session = await openSettledCompositionPage(html, server.url, {
168+
navigationTimeoutMs: options.timeout,
168169
renderReadyTimeoutMs: options.timeout,
169170
renderReadyWarningSuffix: "checking the current page state",
170171
browserGpuMode: resolveCliChromeGpuMode(),
@@ -225,6 +226,7 @@ export async function captureFindingCrops(
225226
const written: string[] = [];
226227
try {
227228
const session = await openSettledCompositionPage(html, server.url, {
229+
navigationTimeoutMs: options.timeout,
228230
renderReadyTimeoutMs: options.timeout,
229231
renderReadyWarningSuffix: "capturing finding crops",
230232
browserGpuMode: resolveCliChromeGpuMode(),

packages/cli/src/utils/renderArgs.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,17 @@ describe("resolveDiagnosticNavigationTimeoutMs", () => {
118118
resolveDiagnosticNavigationTimeoutMs({ PRODUCER_PAGE_NAVIGATION_TIMEOUT_MS: "invalid" }),
119119
).toBe(10_000);
120120
});
121+
122+
it("raises the diagnostic navigation budget to a larger caller-provided minimum", () => {
123+
expect(resolveDiagnosticNavigationTimeoutMs({}, 30_000)).toBe(30_000);
124+
expect(resolveDiagnosticNavigationTimeoutMs({}, 3_000)).toBe(10_000);
125+
expect(
126+
resolveDiagnosticNavigationTimeoutMs(
127+
{ PRODUCER_PAGE_NAVIGATION_TIMEOUT_MS: "90000" },
128+
30_000,
129+
),
130+
).toBe(90_000);
131+
});
121132
});
122133

123134
describe("parseCompositionEntryArg", () => {

packages/cli/src/utils/renderArgs.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,20 @@ export function resolveBrowserTimeoutMsArg(raw: string | undefined): number | un
118118
return result.value;
119119
}
120120

121-
/** Navigation budget shared by snapshot/check/inspect browser diagnostics. */
121+
/**
122+
* Navigation budget shared by snapshot/check/inspect browser diagnostics.
123+
*
124+
* The environment variable remains the historical global override. Callers
125+
* with their own timeout knob can supply a minimum without shortening that
126+
* override or the existing 10-second default.
127+
*/
122128
export function resolveDiagnosticNavigationTimeoutMs(
123129
env: Record<string, string | undefined> = process.env,
130+
minimumTimeoutMs = 0,
124131
): number {
125132
const parsed = Number(env.PRODUCER_PAGE_NAVIGATION_TIMEOUT_MS);
126-
return Number.isFinite(parsed) && parsed > 0 ? parsed : 10_000;
133+
const configured = Number.isFinite(parsed) && parsed > 0 ? parsed : 10_000;
134+
return Math.max(configured, minimumTimeoutMs);
127135
}
128136

129137
// ── --composition ──────────────────────────────────────────────────────

skills-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"files": 121
2727
},
2828
"hyperframes-cli": {
29-
"hash": "966972db5ab8f932",
29+
"hash": "42b621ca580541b6",
3030
"files": 11
3131
},
3232
"hyperframes-core": {

skills/hyperframes-cli/references/lint-validate-inspect.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ npx hyperframes check --samples 15 # denser timeline sweep (default 9)
3636
npx hyperframes check --at 1.5,4,7.25 # explicit hero-frame timestamps
3737
npx hyperframes check --at-transitions # also sample every tween start/end boundary
3838
npx hyperframes check --tolerance 4 # allowed overflow px before reporting (default 2)
39-
npx hyperframes check --timeout 5000 # ms for the initial settle (default 3000)
39+
npx hyperframes check --timeout 30000 # initial render-ready + navigation minimum in ms (defaults: 3000 / 10000)
4040
npx hyperframes check --no-contrast # skip the WCAG audit while iterating
4141
npx hyperframes check --strict # exit non-zero on warnings too (default: only errors)
4242
```

0 commit comments

Comments
 (0)