0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-11 02:59:07 +08:00
discourse/spec/system/user_activity_scroll_restoration_spec.rb
David Battersby b5961484c9
FIX: preserve scroll position when returning to user activity streams (#42435)
Scrolling a user activity stream far enough to trigger infinite scroll,
opening a topic, then pressing back would land the user higher up the
page than where they left off.

The scroll position was being restored correctly, but the stream was
refetched from scratch, so the page only held its first page of items
and was too short to scroll back to the saved offset — the browser
clamped it.

On a back/forward navigation we now reuse the stream we left behind,
including everything infinite scroll appended, so the page is the same
height it was and the restored position lands where the user was
reading. The stream is stored per history entry via the historyStore
service, so ordinary forward navigation still loads a fresh stream.

Meta bug report:
https://meta.discourse.org/t/regression-u-username-activity-loses-scroll-position-after-browser-back/406292
2026-08-07 16:36:28 +04:00

41 lines
1.2 KiB
Ruby
Vendored

# frozen_string_literal: true
describe "User activity scroll restoration" do
before_all { UserActionManager.enable }
fab!(:user)
# 40 replies: the stream serves 30 per page, so the rest arrive via infinite scroll
fab!(:topics) do
Fabricate
.times(5, :topic)
.each do |topic|
Fabricate
.times(9, :post, topic:, user:)
.each { |post| UserActionManager.post_created(post) }
end
end
let(:activity_stream) { PageObjects::Pages::UserActivityStream.new }
it "takes the user back to where they were reading after they open a post and go back" do
activity_stream.visit_replies(user)
expect(activity_stream).to have_items(count: 30)
activity_stream.scroll_to_bottom
expect(activity_stream).to have_items(count: 40)
activity_stream.scroll_to_item(35)
position = activity_stream.scroll_position
activity_stream.open_item(36)
expect(page).to have_css("#topic-title")
page.go_back
expect(activity_stream).to have_items(count: 40)
try_until_success(reason: "scroll position is restored") do
expect(activity_stream.scroll_position).to be_within(20).of(position)
end
end
end