0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-11 02:59:07 +08:00
discourse/spec/system/nested_scroll_restoration_spec.rb
Mark VanLandingham 5b768a3fa3
DEV: Make nested scroll restoration spec deterministic (#42096)
Previously, the nested scroll restoration system spec raced pagination
and sampled transient scroll positions, which caused intermittent
failures.

This change pauses pagination until the user scroll is complete and
verifies the visible post remains stable through the restoration retry
window.

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-28 11:50:33 -05:00

98 lines
3.4 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe "Nested view scroll restoration" do
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
fab!(:topic) { Fabricate(:topic, user: user) }
fab!(:op) { Fabricate(:post, topic: topic, user: user, post_number: 1) }
fab!(:root_posts) do
60.times.map do |index|
Fabricate(
:post,
topic: topic,
user: Fabricate(:user),
raw: "Root post number #{index + 1}\n\n#{"filler text " * 300}",
reply_to_post_number: nil,
)
end
end
let(:nested_view) { PageObjects::Pages::NestedView.new }
before do
SiteSetting.nested_replies_enabled = true
Fabricate(:nested_topic, topic: topic)
sign_in(user)
end
it "lets the user keep scrolling after returning to a topic", :aggregate_failures do
nested_view.visit_nested(topic)
expect(nested_view).to have_nested_view
nested_view.scroll_to_position(5000)
nested_view.visit_nested(topic)
expect(nested_view).to have_nested_view
try_until_success(reason: "scroll anchor restores after render") do
expect(nested_view.current_scroll_position).to be_within(10).of(5000)
end
positions = nested_view.scroll_during_pending_restore(distance: 3000)
expect(positions["restored"]).to be_within(10).of(5000)
expect(positions["afterUserScroll"]).to be > positions["restored"] + 2500
expect(positions["afterRetries"]).to be_within(10).of(positions["afterUserScroll"])
end
it "restores after pagination when the user does not scroll", :aggregate_failures do
target_post = root_posts[24]
nested_view.visit_nested(topic).disable_cloaking
expect(nested_view).to have_root_post_count(20)
nested_view.scroll_to_bottom
expect(nested_view).to have_root_post_count(40)
nested_view.scroll_to_post(target_post)
saved_position = nested_view.current_scroll_position
nested_view.visit_nested(topic)
expect(nested_view).to have_root_post_count(20)
try_until_success(reason: "scroll anchor restores after paginated roots load") do
expect(nested_view).to have_root_post_count(40)
expect(nested_view.current_scroll_position).to be_within(10).of(saved_position)
end
end
it "lets the user keep scrolling when pagination loads the restored post", :aggregate_failures do
target_post = root_posts[24]
nested_view.visit_nested(topic).disable_cloaking
expect(nested_view).to have_root_post_count(20)
nested_view.scroll_to_bottom
expect(nested_view).to have_root_post_count(40)
nested_view.scroll_to_post(target_post)
saved_position = nested_view.current_scroll_position
nested_view.with_root_pagination_paused(topic) do |pagination|
nested_view.visit_nested(topic)
expect(nested_view).to have_root_post_count(20)
pagination.wait
restored_position = nested_view.current_scroll_position
after_user_scroll_position = nested_view.user_scroll_by(distance: -1000)
centered_post_number = nested_view.centered_root_post_number
pagination.resume
expect(restored_position).to be < saved_position
expect(after_user_scroll_position).to be < restored_position - 500
expect(nested_view).to have_root_post_count(40)
expect(nested_view.scroll_position_after_restore_window).to be < saved_position
expect(nested_view.centered_root_post_number).to eq(centered_post_number)
end
end
end