Skip to content

fix: settle adaptive navigation before capture - #2345

Merged
chubes4 merged 1 commit into
mainfrom
fix-2343-adaptive-navigation-capture
Aug 24, 2026
Merged

fix: settle adaptive navigation before capture#2345
chubes4 merged 1 commit into
mainfrom
fix-2343-adaptive-navigation-capture

Conversation

@chubes4

@chubes4 chubes4 commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • track main-frame navigation from request start through domcontentloaded before final browser capture
  • bound both navigation settlement and page.content() itself inside the existing adaptive stabilization/command wall budget
  • classify unresolved adaptive capture as incomplete, retain available steps/errors/network/screenshot evidence, and omit unavailable artifact refs instead of throwing a workload execution error

Root cause

Adaptive exploration could finish after its final action while the main frame was still navigating. The actions runner then called page.content() directly. Playwright either rejected that call with Unable to retrieve content because the page is navigating and changing the content or kept it pending until outside the intended capture budget, which escaped through the fuzz workload boundary as fuzz_suite_runtime_workload_execution_error.

Capture lifecycle

The Playground capture session now observes main-frame navigation requests and considers them settled on domcontentloaded or request failure. HTML capture first waits for observed navigation, bounds every page.content() attempt, and retries only the exact Playwright navigation race while budget remains.

If navigation cannot settle, adaptive evidence is marked incomplete with browser_adaptive_capture_navigation_unsettled. A requested screenshot gets one bounded attempt from the same capture budget; if unavailable, browser_adaptive_capture_screenshot_unavailable is retained while steps/errors/network evidence remains intact. Normal settled capture still performs one page.content() call and emits the same HTML and screenshot artifacts.

Before / after evidence

Before:

  • WP Codebox 0.23.4
  • run run_857b993f1e374f8da65ae93afbd316e1
  • runtime runtime-mt7ib5r0-27v2pu
  • case studio-gardner-social-operator-adaptive-1
  • result: raw page.content() race became fuzz_suite_runtime_workload_execution_error

After exact disposable replay:

  • run run_70e71ece0b9e4e7c9cc1194d6db1a464
  • runtime runtime-mt7k7icc-cuxi1r
  • campaign status: incomplete, timedOut: 0, diagnostic campaign-case-resource-exhausted
  • capture diagnostics: navigation settlement budgetMs: 100, waitedMs: 100; screenshot attempt bounded at 100ms
  • retained artifacts: browser steps, errors, network/request coverage/waterfall, adaptive exploration, redirect diagnostics, and action summary
  • no fuzz_suite_runtime_workload_execution_error
  • strict artifact verification: valid, zero violations, digest cdb62d3e865fae3fbaee3c71d0e6ad6bdbcfef92e28fc4aff635c12221fbf0e6

Verification

  • npx tsx --test tests/browser-actions-navigation-capture.browser.test.ts (5 passed)
  • npx tsx --test tests/browser-actions-navigation-capture.browser.test.ts tests/browser-adaptive-exploration.test.ts (31 passed)
  • npx tsx --test tests/browser-actions-environment.browser.test.ts (10 passed)
  • npm run build
  • node packages/cli/dist/index.js artifacts verify --bundle <replay-bundle> --json (valid, zero violations)
  • git diff --check

npm run check reaches the existing test:generic-primitives gate, then fails on the unrelated clean-tree callback fixture mismatch tracked in #2344. The current callback output adds contentLength, serviceWorkerAllowed, and bodyRewritten, while tests/browser-callback-materialization-contracts.test.ts:245 expects the older exact shape. This PR does not touch that surface.

Fixes #2343

@chubes4
chubes4 merged commit add19c5 into main Aug 24, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: adaptive browser capture races active navigation

1 participant