mirror of
https://github.com/discourse/discourse.git
synced 2026-08-11 02:59:07 +08:00
Previously, clicking the button that toggles a large poll between its results and the ballot scroll-jumped the page far down — often to the bottom — leaving the poll off-screen and the vote seemingly impossible to amend (the browser's native scroll anchoring loses its anchor node when the toggle removes the results table the user is scrolled into). This change pins the poll's button row and restores its viewport position with `window.scrollBy` after the swap, so the poll stays exactly where the user was looking when switching between results and voting. Meta: https://meta.discourse.org/t/large-poll-bug-users-cannot-amend-votes-on-open-polls/405511
80 lines
2.5 KiB
Ruby
Vendored
80 lines
2.5 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
module PageObjects
|
|
module Pages
|
|
class Poll < PageObjects::Pages::Base
|
|
def initialize(topic_page: nil)
|
|
@topic_page = topic_page || PageObjects::Pages::Topic.new
|
|
end
|
|
|
|
def has_poll_for_post?(post)
|
|
@topic_page.post_by_number(post.post_number).has_css?(".poll")
|
|
end
|
|
|
|
def find_poll_for_post(post)
|
|
@topic_page.post_by_number(post.post_number).find(".poll")
|
|
end
|
|
|
|
def has_option?(post, option)
|
|
post_element = @topic_page.post_by_number(post.post_number)
|
|
post_element.has_css?(".poll .option-text", text: option)
|
|
end
|
|
|
|
def has_no_option?(post, option)
|
|
post_element = @topic_page.post_by_number(post.post_number)
|
|
post_element.has_no_css?(".poll .option-text", text: option)
|
|
end
|
|
|
|
def vote_for_option(post, option)
|
|
post_element = @topic_page.post_by_number(post.post_number)
|
|
post_element.find("li[data-poll-option-id] button", text: option).click
|
|
end
|
|
|
|
def has_vote_count?(post, count)
|
|
post_element = @topic_page.post_by_number(post.post_number)
|
|
post_element.has_css?(".poll .info-number", text: count.to_s)
|
|
end
|
|
|
|
def click_cast_votes(post)
|
|
@topic_page.post_by_number(post.post_number).find(".poll-buttons .cast-votes").click
|
|
end
|
|
|
|
def has_results_toggle?(post)
|
|
@topic_page.post_by_number(post.post_number).has_css?(".poll-buttons button.toggle-results")
|
|
end
|
|
|
|
def scroll_results_toggle_into_view
|
|
button = find(".poll-buttons button.toggle-results")
|
|
page.execute_script("arguments[0].scrollIntoView({ block: 'center' });", button)
|
|
end
|
|
|
|
def click_results_toggle
|
|
page.execute_script(
|
|
"document.querySelector('.poll-buttons button.toggle-results').click();",
|
|
)
|
|
end
|
|
|
|
def has_voting_options?(post)
|
|
@topic_page.post_by_number(post.post_number).has_css?(".poll ul.options")
|
|
end
|
|
|
|
def has_poll_within_viewport?
|
|
try_until_success { expect(poll_within_viewport?).to eq(true) }
|
|
true
|
|
rescue RSpec::Expectations::ExpectationNotMetError
|
|
false
|
|
end
|
|
|
|
private
|
|
|
|
def poll_within_viewport?
|
|
page.evaluate_script(<<~JS)
|
|
(() => {
|
|
const rect = document.querySelector(".poll")?.getBoundingClientRect();
|
|
return rect ? rect.top < window.innerHeight && rect.bottom > 0 : false;
|
|
})()
|
|
JS
|
|
end
|
|
end
|
|
end
|
|
end
|