Description
#106 reported navigate hard-coding waitUntil: 'load'. That fix landed, but the same root cause has a second call site that was not covered.
On main today:
// src/browser/runtime/local-cloak/actions.ts:116 — navigate, fixed by #106/#107
await lease.page.goto(command.url, { waitUntil: command.waitUntil === 'none' ? 'commit' : 'load' });
// src/browser/runtime/local-cloak/session-manager.ts:249 — newPage, still hardcoded
await acquired.page.goto(input.url, { waitUntil: 'load' });
So webcmd browser navigate --wait-until none now works, while webcmd browser tab new --url <url> (and the hosted tab-open path) still blocks until load fires. On a site that never goes idle — a streaming dashboard, a long-poll app shell, an ad-heavy page with a hanging subresource — opening a tab still hangs, which is the exact failure #106 was filed about.
Why it was missed
The gap is structural rather than a missed edit. newPage has no waitUntil in its signature at all:
// src/browser/runtime/local-cloak/session-manager.ts:237
async newPage(input: SessionKeyInput & { url?: string }): Promise<CloakPageLease>
And its only caller drops the field, even though it is available on the command object it is reading from:
// src/browser/runtime/local-cloak/actions.ts:156-163 — 'tabs' / 'new'
const lease = await manager.newPage({
profileId: resolveCloakCommandProfileId(manager, command),
session: command.session,
surface: command.surface,
siteSession: command.siteSession,
idleTimeout: command.idleTimeout,
url: command.url,
windowMode: command.windowMode,
// command.waitUntil is never passed
});
Every other layer is already plumbed for this:
| Layer |
Status |
src/browser/protocol.ts:36 |
waitUntil?: 'load' | 'none' already on the command type |
src/browser/base-page.ts:167 |
abstract goto already accepts waitUntil |
src/browser/cdp.ts:210 |
honours it (:215, :221) |
src/browser/page.ts:103 |
honours it (:107, :134) |
session-manager.ts:237 |
the only type in the chain missing it |
Suggested fix
Three small edits, all in the local-cloak runtime:
- Widen the
newPage input to SessionKeyInput & { url?: string; waitUntil?: 'load' | 'none' } (session-manager.ts:237).
- Pass
waitUntil: command.waitUntil from the tabs/new branch (actions.ts:156-163).
- Use it at
session-manager.ts:249 instead of the hardcoded literal.
Related inconsistency worth folding in
actions.ts:116 translates 'none' into Playwright's 'commit', while cdp.ts:215 and page.ts:134 branch on the string 'none' directly. Two vocabularies for one concept across three files is part of why the second call site was easy to overlook. A single shared helper — toGotoWaitUntil(waitUntil) — would make the next such change land everywhere at once.
Verification
Checked against main (53310bf) and upstream/main; both are identical for every file named here. A full sweep of waitUntil across src/ (excluding tests) shows session-manager.ts:249 as the only remaining hardcoded 'load' on a goto call.
Description
#106 reported
navigatehard-codingwaitUntil: 'load'. That fix landed, but the same root cause has a second call site that was not covered.On
maintoday:So
webcmd browser navigate --wait-until nonenow works, whilewebcmd browser tab new --url <url>(and the hosted tab-open path) still blocks untilloadfires. On a site that never goes idle — a streaming dashboard, a long-poll app shell, an ad-heavy page with a hanging subresource — opening a tab still hangs, which is the exact failure #106 was filed about.Why it was missed
The gap is structural rather than a missed edit.
newPagehas nowaitUntilin its signature at all:And its only caller drops the field, even though it is available on the command object it is reading from:
Every other layer is already plumbed for this:
src/browser/protocol.ts:36waitUntil?: 'load' | 'none'already on the command typesrc/browser/base-page.ts:167gotoalready acceptswaitUntilsrc/browser/cdp.ts:210:215,:221)src/browser/page.ts:103:107,:134)session-manager.ts:237Suggested fix
Three small edits, all in the local-cloak runtime:
newPageinput toSessionKeyInput & { url?: string; waitUntil?: 'load' | 'none' }(session-manager.ts:237).waitUntil: command.waitUntilfrom thetabs/newbranch (actions.ts:156-163).session-manager.ts:249instead of the hardcoded literal.Related inconsistency worth folding in
actions.ts:116translates'none'into Playwright's'commit', whilecdp.ts:215andpage.ts:134branch on the string'none'directly. Two vocabularies for one concept across three files is part of why the second call site was easy to overlook. A single shared helper —toGotoWaitUntil(waitUntil)— would make the next such change land everywhere at once.Verification
Checked against
main(53310bf) andupstream/main; both are identical for every file named here. A full sweep ofwaitUntilacrosssrc/(excluding tests) showssession-manager.ts:249as the only remaining hardcoded'load'on agotocall.