Skip to content

iter-124: navigate probe actor refresh + cookies contract test - #163

Merged
ractive merged 4 commits into
mainfrom
iter-124/live-sweep-followups
Jul 19, 2026
Merged

iter-124: navigate probe actor refresh + cookies contract test#163
ractive merged 4 commits into
mainfrom
iter-124/live-sweep-followups

Conversation

@ractive

@ractive ractive commented Jul 19, 2026

Copy link
Copy Markdown
Owner

Summary

  • Post-merge live sweep after iters 121–123 found 2 red live tests (both reproduced serially on a clean single FF152 instance); this PR fixes both.
  • Product bug (navigate): ReadyStateProbe.console_actor was captured before navigateTo; Firefox invalidates that actor when the new document commits, so every probe attempt failed with noSuchActor (18/18 instrumented) and the iter-122 fast path silently fell back to the ~5.6–5.9s events-budget burn. Fix: refresh_probe_console_actor() re-resolves via TabActor::get_target when dom-loading commits (lazy fallback before the first probe on quiet streams), mirroring ConnectedTab::refresh_target. wait_for_doc_complete now takes Option<&mut ReadyStateProbe>.
  • Stale test expectation (cookies): live_cookies_surfaces_js_readable_cookie asserted source == "document.cookie" — only ever true while StorageActor enumeration was dead (pre-iter-121). The merge in cookies.rs correctly prefers the StorageActor entry (real flags, no source field). Test now pins the StorageActor-or-fallback contract instead of the implementation detail.
  • Plan: kb/iterations/iteration-124-live-sweep-followups.md; remaining dogfood-61 moderate bugs filed as iters 125–127.

Test plan

  • live_navigate_default_fast serial post-fix: 2 passed in 4.07s (was 5.6–5.9s, red)
  • live_cookies_surfaces_js_readable_cookie serial post-fix: PASS (storage_actor_sourced=true)
  • 14 AC-relevant live tests across live_cookies / live_navigate_default_fast / live_123 filters: all green (5+5+4)
  • cargo fmt / cargo clippy --workspace --all-targets -- -D warnings / cargo test --workspace -q: clean (33 blocks, 1687 passed, 0 failed)
  • FF_RDP_LIVE_TESTS=1 cargo xtask check-iteration-ready: 10/10 PASS

🤖 Generated with Claude Code

ractive added a commit that referenced this pull request Jul 19, 2026
…round-trips

Local PR review (#163) found three issues in the console-actor refresh fix:

1. HIGH: refresh_probe_console_actor set probe_refreshed = true even when
   TabActor::get_target returned Err. A single transient failure (the new
   docshell not yet queryable server-side) permanently stranded the probe
   on its stale actor for the rest of the wait, intermittently
   reintroducing the exact noSuchActor bug this PR fixes. The function now
   returns bool; both call sites in wait_for_doc_complete only latch
   probe_refreshed on Ok, so a failed attempt retries at the next
   probe-timer tick instead of giving up permanently.

2. MED: added unit_navigate_probe_refresh_retries_after_transient_error
   (first getTarget errors, second succeeds, probe recovers and
   short-circuits) and
   unit_navigate_probe_refresh_persistent_error_falls_back_to_timeout
   (every getTarget attempt errors, wait_for_doc_complete falls through
   cleanly to AppError::Timeout with no panic and no hang past the
   budget).

3. LOW: the dom-loading refresh fired for every wait_level, including
   Loading/Interactive with a non-empty URL, where the refreshed actor is
   never consumed (those cases resolve straight from the event's own url).
   Gated on wait_level == WaitLevel::Complete || url.is_empty() so the
   round-trip is only paid when something will actually use it.
@ractive

ractive commented Jul 19, 2026

Copy link
Copy Markdown
Owner Author

Local review round (local-only mode)

# File:Line Issue Severity Resolution
1 navigate.rs refresh call sites probe_refreshed latched true even on Err — one transient getTarget failure permanently stranded the probe on the stale actor high refresh_probe_console_actor returns bool; latch only on success, retry next probe tick (9d0466a)
2 navigate.rs tests No coverage of the getTarget Err branch med Added unit_navigate_probe_refresh_retries_after_transient_error + unit_navigate_probe_refresh_persistent_error_falls_back_to_timeout (9d0466a)
3 navigate.rs dom-loading handler Refresh round-trip paid on Loading/Interactive waits that never consume it low Gated to wait_level == Complete || url.is_empty(); consumption paths traced to confirm no gap (9d0466a)

Post-fix: gates clean (fmt/clippy/workspace 33 blocks 0 fail), serial live live_navigate_default_fast 5/5 in 8.50s, check-iteration-ready 10/10.

ractive and others added 4 commits July 19, 2026 16:43
The iter-122 Theme A interleaved readystate probe captured its console
actor from the pre-navigation target and never refreshed it. Firefox
tears down the old docshell (and, cross-process, the child process)
once the new document commits, invalidating that actor ID — every
subsequent probe eval failed with noSuchActor for the rest of the
wait, silently defeating the fast path and falling through to the
full events-budget timeout (~5.6-5.9s instead of the sub-4s the
iter-122 AC requires).

Refresh ReadyStateProbe::console_actor via TabActor::get_target once
dom-loading commits (or lazily before the first probe attempt if the
events stream is quiet), matching the existing refresh_target pattern
used elsewhere in the connect_tab module.

live_navigate_default_fast now completes in ~9.7s total across 5 tests
(was 33.85s with the target test alone timing out at 5.9s).
live_cookies_surfaces_js_readable_cookie asserted the probe cookie's
source was always "document.cookie" — true only because iter-121's
predecessor state had StorageActor cookie enumeration dead on FF152,
making the document.cookie fallback the sole path that ever surfaced
a JS-set cookie without a Domain= attribute.

iter-121 fixed StorageActor enumeration, and it turns out FF152's
StorageActor does enumerate this cookie shape. The cookies command's
merge logic (crates/ff-rdp-cli/src/commands/cookies.rs) then correctly
drops the now-redundant document.cookie duplicate, so the surviving
entry has no `source` field (StorageActor-derived CookieInfo doesn't
serialize one) instead of "document.cookie" — strictly better data
(carries isHttpOnly/isSecure/sameSite), not a regression.

Rewrite the assertion to accept either valid shape: StorageActor-
sourced (no source field, isHttpOnly present) or document.cookie-
sourced (source: "document.cookie"), so the test pins the actual
contract instead of an implementation detail that iter-121 changed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…round-trips

Local PR review (#163) found three issues in the console-actor refresh fix:

1. HIGH: refresh_probe_console_actor set probe_refreshed = true even when
   TabActor::get_target returned Err. A single transient failure (the new
   docshell not yet queryable server-side) permanently stranded the probe
   on its stale actor for the rest of the wait, intermittently
   reintroducing the exact noSuchActor bug this PR fixes. The function now
   returns bool; both call sites in wait_for_doc_complete only latch
   probe_refreshed on Ok, so a failed attempt retries at the next
   probe-timer tick instead of giving up permanently.

2. MED: added unit_navigate_probe_refresh_retries_after_transient_error
   (first getTarget errors, second succeeds, probe recovers and
   short-circuits) and
   unit_navigate_probe_refresh_persistent_error_falls_back_to_timeout
   (every getTarget attempt errors, wait_for_doc_complete falls through
   cleanly to AppError::Timeout with no panic and no hang past the
   budget).

3. LOW: the dom-loading refresh fired for every wait_level, including
   Loading/Interactive with a non-empty URL, where the refreshed actor is
   never consumed (those cases resolve straight from the event's own url).
   Gated on wait_level == WaitLevel::Complete || url.is_empty() so the
   round-trip is only paid when something will actually use it.
@ractive
ractive force-pushed the iter-124/live-sweep-followups branch from 9d0466a to 1740642 Compare July 19, 2026 14:43
@ractive
ractive merged commit 2bc332e into main Jul 19, 2026
10 checks passed
@ractive
ractive deleted the iter-124/live-sweep-followups branch July 19, 2026 14:43
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.

1 participant