Skip to content

constellation: Queue session history traversals - #47293

Merged
mrobinson merged 1 commit into
servo:mainfrom
mrobinson:history-traversal
Aug 18, 2026
Merged

mrobinson merged 1 commit into
servo:mainfrom
mrobinson:history-traversal

Conversation

@mrobinson

Copy link
Copy Markdown
Member

Instead of running history traversals (moving backward and forward in
the session history) immediately, only run each traversal after the
previous one has finished. Traversals may not finish immediately if a
page needs to be reloaded due to being a sufficient distance away in the
back-forward list to not be cached or because an unload handler ran.

This fixes issues with intermittency when running history navigation
tests. Previously, history traversals were run immediately (instead of
being queued) which could lead to nondeterminate navigation outcomes.

Testing: This should eliminate test flakiness on the CI.
Fixes: #21383.

@mrobinson
mrobinson requested a review from gterzian as a code owner August 17, 2026 12:31
@servo-highfive servo-highfive added S-awaiting-review There is new code that needs to be reviewed. S-needs-rebase There are merge conflict errors. labels Aug 17, 2026
@servo-highfive servo-highfive added S-needs-rebase There are merge conflict errors. and removed S-needs-rebase There are merge conflict errors. labels Aug 17, 2026
@mrobinson mrobinson added the T-linux-wpt Do a try run of the WPT label Aug 17, 2026
@github-actions github-actions Bot removed the T-linux-wpt Do a try run of the WPT label Aug 17, 2026
@github-actions

Copy link
Copy Markdown

🔨 Triggering try run (#32031410554) for Linux (WPT)

@servo-highfive servo-highfive added S-needs-rebase There are merge conflict errors. and removed S-needs-rebase There are merge conflict errors. labels Aug 17, 2026
@github-actions

Copy link
Copy Markdown

Test results for linux-wpt from try job (#32031410554):

Flaky unexpected result (35)
  • CRASH [expected OK] /_mozilla/mozilla/iframe-contentDocument.html
  • CRASH [expected OK] /_webgl/conformance/reading/read-pixels-test.html
  • CRASH [expected OK] /_webgl/conformance/uniforms/no-over-optimization-on-uniform-array-06.html
  • CRASH [expected OK] /_webgl/conformance/uniforms/no-over-optimization-on-uniform-array-14.html
  • TIMEOUT [expected OK] /_webgl/conformance/uniforms/no-over-optimization-on-uniform-array-15.html
    • NOTRUN [expected PASS] subtest: Overall test
  • CRASH [expected OK] /_webgl/conformance2/transform_feedback/transform_feedback.html
  • FAIL [expected PASS] /css/css-backgrounds/background-size-042.html
  • FAIL [expected PASS] /css/css-sizing/dynamic-available-size-iframe.html (#45763)
  • CRASH [expected OK] /dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html
  • TIMEOUT [expected OK] /fetch/content-encoding/br/big-br-body.https.any.worker.html
    • TIMEOUT [expected PASS] subtest: large br data should be decompressed successfully

      Test timed out
      

    • NOTRUN [expected FAIL] subtest: large br data should be decompressed successfully with byte stream
  • TIMEOUT [expected OK] /fetch/content-encoding/gzip/big-gzip-body.https.any.worker.html
    • TIMEOUT [expected PASS] subtest: large gzip data should be decompressed successfully

      Test timed out
      

    • NOTRUN [expected FAIL] subtest: large gzip data should be decompressed successfully with byte stream
  • TIMEOUT [expected OK] /fetch/content-encoding/zstd/big-zstd-body.https.any.html
  • TIMEOUT [expected OK] /fetch/content-encoding/zstd/big-zstd-body.https.any.worker.html
    • TIMEOUT [expected PASS] subtest: large zstd data should be decompressed successfully

      Test timed out
      

    • NOTRUN [expected FAIL] subtest: large zstd data should be decompressed successfully with byte stream
  • TIMEOUT /fetch/metadata/generated/css-images.sub.tentative.html (#29047)
    • TIMEOUT [expected PASS] subtest: background-image sec-fetch-mode - Not sent to non-trustworthy cross-site destination

      Test timed out
      

    • FAIL [expected PASS] subtest: content sec-fetch-user - Not sent to non-trustworthy cross-site destination

      assert_unreached: Reached unreachable code
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/005.html (#27062)
    • PASS [expected FAIL] subtest: Link with onclick navigation and href navigation
  • OK /html/browsers/browsing-the-web/navigating-across-documents/javascript-url-return-value-handling-dynamic.html
    • FAIL [expected PASS] subtest: 0041 set in href="" targeting a frame and clicked

      assert_equals: expected "A" but got ""
      

    • FAIL [expected PASS] subtest: 0080 00FF set in href="" targeting a frame and clicked

      assert_equals: expected "�ÿ" but got ""
      

    • FAIL [expected PASS] subtest: 0080 00FF 0100 set in href="" targeting a frame and clicked

      assert_equals: expected "�ÿĀ" but got ""
      

    • FAIL [expected PASS] subtest: D83D DE0D set in href="" targeting a frame and clicked

      assert_equals: expected "😍" but got ""
      

  • OK [expected TIMEOUT] /html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/form-submit-button-click.html (#44099)
    • FAIL [expected TIMEOUT] subtest: Replace before load, triggered by submitButton.click()

      assert_equals: expected "http://web-platform.test:8000/common/blank.html?thereplacement=" but got "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/resources/code-injector.html?pipe=sub(none)&code=%0A%20%20%20%20const%20form%20%3D%20document.createElement(%22form%22)%3B%0A%20%20%20%20form.action%20%3D%20%22%2Fcommon%2Fblank.html%22%3B%0A%0A%20%20%20%20const%20input%20%3D%20document.createElement(%22input%22)%3B%0A%20%20%20%20input.type%20%3D%20%22hidden%22%3B%0A%20%20%20%20input.name%20%3D%20%22thereplacement%22%3B%0A%20%20%20%20form.append(input)%3B%0A%0A%20%20%20%20const%20button%20%3D%20document.createElement(%22button%22)%3B%0A%20%20%20%20button.type%20%3D%20%22submit%22%3B%0A%20%20%20%20form.append(button)%3B%0A%0A%20%20%20%20document.currentScript.before(form)%3B%0A%20%20%20%20button.click()%3B%0A%20%20"
      

  • CRASH [expected ERROR] /html/browsers/history/the-location-interface/location_replace_session_history.html (#41896)
  • OK /html/browsers/windows/embedded-opener-remove-frame.html (#23867)
    • PASS [expected FAIL] subtest: opener of discarded auxiliary browsing context
  • TIMEOUT [expected OK] /html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)
    • TIMEOUT [expected FAIL] subtest: Host element with delegatesFocus should support autofocus

      Test timed out
      

    • NOTRUN [expected FAIL] subtest: Host element with delegatesFocus including no focusable descendants should be skipped
    • NOTRUN [expected FAIL] subtest: Area element should support autofocus
  • TIMEOUT /html/semantics/embedded-content/media-elements/preserves-pitch.html (#40352)
    • PASS [expected TIMEOUT] subtest: Speed-ups should not change the pitch when preservesPitch=true
    • TIMEOUT [expected NOTRUN] subtest: Slow-downs should not change the pitch when preservesPitch=true

      Test timed out
      

  • CRASH [expected OK] /html/semantics/embedded-content/the-img-element/image-loading-lazy-in-scroller-nested.html
  • TIMEOUT [expected OK] /html/user-activation/navigation-state-reset-sameorigin.html (#45151)
    • TIMEOUT [expected FAIL] subtest: Post-navigation state reset.

      Test timed out
      

  • OK /infrastructure/testdriver/click_iframe.html
    • FAIL [expected PASS] subtest: TestDriver click on a document in an iframe

      Unhandled rejection: assert_unreached: click failed Reached unreachable code
      

  • OK /mixed-content/tentative/autoupgrades/mixed-content-cors.https.sub.html (#41123)
    • FAIL [expected PASS] subtest: Cross-Origin audio should get upgraded even if CORS is set

      assert_equals: Length of other host audio is correct expected 1 but got Infinity
      

  • ERROR [expected TIMEOUT] /performance-timeline/not-restored-reasons/abort-block-bfcache.window.html (#42802)
  • TIMEOUT [expected OK] /pointerevents/compat/pointerevent_touch-action_two-finger_interaction.html (#44693)
    • NOTRUN [expected PASS] subtest: touch two-finger pan on 'touch-action: pan-x pan-y'
    • NOTRUN [expected FAIL] subtest: touch two-finger pan on 'touch-action: pinch-zoom'
  • OK /preload/prefetch-document.html (#37210)
    • FAIL [expected PASS] subtest: different-site document prefetch with 'as=document' should not be consumed

      assert_equals: expected 2 but got 1
      

  • OK /sanitizer-api/sanitizer-inert-document.html (#45260)
    • FAIL [expected PASS] subtest: Test whether setHTML loads the image.

      promise_test: Unhandled rejection with value: "The server observed a request. It shouldn't have."
      

    • PASS [expected FAIL] subtest: Test whether setHTMLUnsafe loads the image.
  • CRASH [expected OK] /svg/animations/svgpath-animation-2.tentative.html
  • OK /touch-events/single-tap-when-touchend-listener-use-sync-xhr.html (#41175)
    • PASS [expected FAIL] subtest: Click event should be fired when touchend opens synchronous XHR
  • CRASH [expected OK] /trusted-types/require-trusted-types-for.html
  • TIMEOUT /trusted-types/trusted-types-navigation.html?06-10 (#37920)
    • FAIL [expected PASS] subtest: Navigate a frame via anchor with javascript:-urls in report-only mode.

      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

  • TIMEOUT [expected OK] /trusted-types/trusted-types-navigation.html?16-20 (#44835)
    • TIMEOUT [expected PASS] subtest: Navigate a frame via area with javascript:-urls w/ default policy in report-only mode.

      Test timed out
      

  • TIMEOUT [expected OK] /webstorage/storage_session_setitem_quotaexceedederr.window.html
Stable unexpected results that are known to be intermittent (19)
  • OK /beacon/beacon-basic.https.window.html (#41723)
    • FAIL [expected PASS] subtest: Payload size restriction should be accumulated: type = string

      assert_false: expected false got true
      

    • FAIL [expected PASS] subtest: Payload size restriction should be accumulated: type = arraybuffer

      assert_false: expected false got true
      

    • FAIL [expected PASS] subtest: Payload size restriction should be accumulated: type = blob

      assert_false: expected false got true
      

  • OK /css/css-fonts/variations/at-font-face-font-matching.html (#20684)
    • FAIL [expected PASS] subtest: Matching font-stretch: '110%' should prefer '105%' over '100%'

      assert_equals: Unexpected font on test element expected 487 but got 532
      

  • OK /dom/nodes/moveBefore/iframe-document-preserve.window.html (#43152)
    • PASS [expected FAIL] subtest: moveBefore(): cross-origin iframe is preserved: remove new parent
    • PASS [expected FAIL] subtest: moveBefore(): cross-origin iframe is preserved: remove self
  • OK [expected ERROR] /fetch/fetch-later/quota/same-origin-iframe/accumulated-oversized-payload.https.window.html (#41705)
  • OK [expected ERROR] /focus/focus-event-after-switching-iframes.sub.html (#40368)
  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-window-open.html (#28691)
    • PASS [expected FAIL] subtest: load event does not fire on window.open('about:blank')
  • TIMEOUT [expected OK] /html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.html (#30970)
  • OK /html/interaction/focus/the-autofocus-attribute/autofocus-dialog.html (#29087)
    • PASS [expected TIMEOUT] subtest: <dialog>-contained autofocus element gets focused when the dialog is shown
  • TIMEOUT /html/semantics/embedded-content/media-elements/autoplay-default-permissions-policy.https.sub.html (#46805)
    • PASS [expected TIMEOUT] subtest: Default "autoplay" feature policy ["self"] allows same-origin iframes.
  • TIMEOUT /html/semantics/embedded-content/media-elements/autoplay-disabled-by-permissions-policy.https.sub.html (#46012, #46804)
    • TIMEOUT [expected FAIL] subtest: Permissions-Policy header: autoplay "none" disallows same-origin iframes.

      Test timed out
      

  • OK /html/semantics/embedded-content/media-elements/media_fragment_seek.html (#24114)
    • PASS [expected FAIL] subtest: Video should seek to time specified in media fragment syntax
  • TIMEOUT [expected OK] /html/syntax/parsing/html5lib_write_single.html?file=processing-instructions (#46206)
    • TIMEOUT [expected FAIL] subtest: <body><?S_S-S_S>

      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: <body><?m-0 data>

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: <body><?xml>

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: <body><?xml-stylesheet>

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: <body><?XML>

      Test timed out
      

    • TIMEOUT [expected PASS] subtest: <body><?XML-stylesheet>

      Test timed out
      

  • OK /html/webappapis/user-prompts/print-during-unload.html (#35944)
    • PASS [expected FAIL] subtest: print() during unload
  • OK /pointerevents/pointerevent_pointercapture_in_frame.html?pen (#45536)
    • FAIL [expected PASS] subtest: Test penpointer capture in same-origin frame: Pointer down at inner frame and set pointer capture.

      assert_true: Timed out waiting for lostpointercapture expected true got false
      

  • OK /pointerevents/pointerevent_pointercapture_in_frame.html?touch (#45445)
    • FAIL [expected PASS] subtest: Test touchpointer capture in same-origin frame: Pointer down at inner frame and set pointer capture.

      assert_true: Timed out waiting for lostpointercapture expected true got false
      

    • FAIL [expected PASS] subtest: Test touchpointer capture in same-origin frame: Pointer down at inner frame and set pointer capture to outer frame should not capture.

      assert_array_equals: Received events: innerFrame received pointerdown,innerFrame received pointermove,innerFrame received pointerup,innerFrame received lostpointercapture lengths differ, expected array ["innerFrame received pointerdown", "innerFrame received pointermove", "innerFrame received pointerup"] length 3, got ["innerFrame received pointerdown", "innerFrame received pointermove", "innerFrame received pointerup", "innerFrame received lostpointercapture"] length 4
      

  • OK /resource-timing/test_resource_timing.html (#25720)
    • PASS [expected FAIL] subtest: PerformanceEntry has correct name, initiatorType, startTime, and duration (img)
  • OK [expected TIMEOUT] /trusted-types/trusted-types-navigation.html?01-05 (#38975)
    • PASS [expected TIMEOUT] subtest: Navigate a window via anchor with javascript:-urls in report-only mode.
    • PASS [expected NOTRUN] subtest: Navigate a window via anchor with javascript:-urls w/ default policy in report-only mode.
    • PASS [expected NOTRUN] subtest: Navigate a frame via anchor with javascript:-urls in enforcing mode.
  • OK [expected TIMEOUT] /trusted-types/trusted-types-navigation.html?31-35 (#38034)
    • PASS [expected TIMEOUT] subtest: Navigate a frame via form-submission with javascript:-urls in report-only mode.
    • PASS [expected NOTRUN] subtest: Navigate a frame via form-submission with javascript:-urls w/ default policy in report-only mode.
    • FAIL [expected NOTRUN] subtest: Navigate a window via form-submission with javascript:-urls w/ a default policy throwing an exception in enforcing mode.

      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

    • FAIL [expected NOTRUN] subtest: Navigate a window via form-submission with javascript:-urls w/ a default policy throwing an exception in report-only mode.

      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

    • FAIL [expected NOTRUN] subtest: Navigate a window via form-submission with javascript:-urls w/ a default policy making the URL invalid in enforcing mode.

      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

  • OK [expected TIMEOUT] /webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html (#29053)
    • FAIL [expected TIMEOUT] subtest: StorageKey: test 3P about:blank window opened from a 3P iframe

      assert_true: about:blank window opened by 3P iframe does not inherit 3P iframe's StorageKey expected true got false
      

@github-actions

Copy link
Copy Markdown

✨ Try run (#32031410554) succeeded.

@TimvdLippe

Copy link
Copy Markdown
Contributor

Can we wait until #46975 is merged, or at least merge these two with a couple of days in between? Both are impactful changes for navigation and to minimise impact on CI stability, I think it's good to be cautious.

@mrobinson

Copy link
Copy Markdown
Member Author

Can we wait until #46975 is merged, or at least merge these two with a couple of days in between? Both are impactful changes for navigation and to minimise impact on CI stability, I think it's good to be cautious.

Sure. This is ready to review and merge now, so it could be merged now or later (if #46975 will be merged soon).

@mrobinson mrobinson added the T-linux-wpt Do a try run of the WPT label Aug 17, 2026
@github-actions github-actions Bot removed the T-linux-wpt Do a try run of the WPT label Aug 17, 2026
@github-actions

Copy link
Copy Markdown

🔨 Triggering try run (#32047871962) for Linux (WPT)

@jdm jdm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! Thanks for tackling this!

browsing_context_id: BrowsingContextId,
new_reloader: NeedsToReload,
) {
) -> Option<PipelineId> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's document what this return value means.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review. I've added documentation for this now.

@github-actions

Copy link
Copy Markdown

✨ Try run (#32047871962) succeeded.

Instead of running history traversals (moving backward and forward in
the session history) immediately, only run each traversal after the
previous one has finished. Traversals may not finish immediately if a
page needs to be reloaded due to being a sufficient distance away in the
back-forward list to not be cached or because an `unload` handler ran.

This fixes issues with intermittency when running history navigation
tests. Previously, history traversals were run immediately (instead of
being queued) which could lead to nondeterminate navigation outcomes.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
@servo-highfive servo-highfive removed the S-needs-rebase There are merge conflict errors. label Aug 18, 2026
@mrobinson
mrobinson enabled auto-merge August 18, 2026 13:27
@mrobinson
mrobinson added this pull request to the merge queue Aug 18, 2026
@servo-highfive servo-highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Aug 18, 2026
Merged via the queue into servo:main with commit 27775d1 Aug 18, 2026
33 checks passed
@mrobinson
mrobinson deleted the history-traversal branch August 18, 2026 16:03
@servo-highfive servo-highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Aug 18, 2026
RichardTjokroutomo pushed a commit to RichardTjokroutomo/servo that referenced this pull request Oct 6, 2026
Instead of running history traversals (moving backward and forward in
the session history) immediately, only run each traversal after the
previous one has finished. Traversals may not finish immediately if a
page needs to be reloaded due to being a sufficient distance away in the
back-forward list to not be cached or because an `unload` handler ran.

This fixes issues with intermittency when running history navigation
tests. Previously, history traversals were run immediately (instead of
being queued) which could lead to nondeterminate navigation outcomes.

Testing: This should eliminate test flakiness on the CI.
Fixes: servo#21383.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-awaiting-review There is new code that needs to be reviewed.

Projects

None yet

4 participants