discourse/plugins/discourse-assign/spec/system/assign_topic_spec.rb
Alan Guo Xiang Tan 55b05c921b
DEV: Add client settled checks for system tests (#35230)
This change seeks to improve the reliability of our system tests by
resolving the lack of consistency in the state of the client side
application between steps in a system test. This is achieved by patching
various action methods in `Capybara::Playwright::Node` and
`Capybara::Playwright::Browser` so that the methods execute an async
JavaScript function on the client side that waits for the client side
application to reach a settled state. A settled state is currently
defined as:

1. No inflight ajax requests. (_messageBus and presence requests are
excluded_)
2. 2 event cycles of the Javascript event loop has happened for for all
"click", "input", "mousedown", "keydown", "focusin", "focusout",
"touchstart", "change", "resize", "scroll" DOM events that fired.

For debugging purposes, a `--debug-client-settled` CLI flag has been
added to `bin/rspec`. When used, detailed debugging information will be
printed to the browser's console as well as to `stdout` of the
`bin/rspec` process.

This change was inspired by
https://evilmartians.com/chronicles/flaky-tests-be-gone-long-lasting-relief-chronic-ci-retry-irritation
and the https://github.com/makandra/capybara-lockstep rubygem.
2025-10-10 11:03:18 +08:00

193 lines
6.3 KiB
Ruby
Vendored

# frozen_string_literal: true
describe "Assign | Assigning topics", type: :system do
let(:topic_page) { PageObjects::Pages::Topic.new }
let(:assign_modal) { PageObjects::Modals::Assign.new }
fab!(:admin1, :admin)
fab!(:admin2, :admin)
fab!(:topic)
fab!(:post) { Fabricate(:post, topic: topic) }
before do
SiteSetting.assign_enabled = true
SiteSetting.prioritize_full_name_in_ux = false
SiteSetting.whispers_allowed_groups = "#{Group::AUTO_GROUPS[:staff]}"
SiteSetting.assign_allowed_on_groups = "#{Group::AUTO_GROUPS[:staff]}"
sign_in(admin1)
end
%w[enabled disabled].each do |value|
before { SiteSetting.glimmer_post_stream_mode = value }
context "when glimmer_post_stream_mode=#{value}" do
describe "with open topic" do
it "can assign and unassign" do
visit "/t/#{topic.id}"
topic_page.click_assign_topic
assign_modal.assignee = admin2
assign_modal.confirm
expect(assign_modal).to be_closed
expect(topic_page).to have_assigned(user: admin2, at_post: 2)
expect(find("#topic .assigned-to")).to have_content(admin2.username)
topic_page.click_unassign_topic
expect(topic_page).to have_unassigned(user: admin2, at_post: 3)
expect(page).to have_no_css("#topic .assigned-to")
end
it "can submit form with shortcut from texatea" do
visit "/t/#{topic.id}"
topic_page.click_assign_topic
assign_modal.assignee = admin2
find("body").send_keys(:tab)
find("body").send_keys(:control, :enter)
expect(assign_modal).to be_closed
expect(topic_page).to have_assigned(user: admin2, at_post: 2)
expect(find("#topic .assigned-to")).to have_content(admin2.username)
end
context "when prioritize_full_name_in_ux setting is enabled" do
before { SiteSetting.prioritize_full_name_in_ux = true }
it "shows the user's name after assign" do
visit "/t/#{topic.id}"
topic_page.click_assign_topic
assign_modal.assignee = admin2
assign_modal.confirm
expect(find("#topic .assigned-to")).to have_content(admin2.name)
end
it "show the user's username if there is no name" do
visit "/t/#{topic.id}"
admin2.name = nil
admin2.save!
admin2.reload
topic_page.click_assign_topic
assign_modal.assignee = admin2
assign_modal.confirm
expect(find("#topic .assigned-to")).to have_content(admin2.username)
end
end
context "when assigns are not public" do
before { SiteSetting.assigns_public = false }
it "assigned small action post has 'private-assign' in class attribute" do
visit "/t/#{topic.id}"
topic_page.click_assign_topic
assign_modal.assignee = admin2
assign_modal.confirm
expect(assign_modal).to be_closed
expect(topic_page).to have_assigned(
user: admin2,
at_post: 2,
class_attribute: ".private-assign",
)
end
end
context "when unassign_on_close is set to true" do
before { SiteSetting.unassign_on_close = true }
it "unassigns the topic on close" do
visit "/t/#{topic.id}"
topic_page.click_assign_topic
assign_modal.assignee = admin2
assign_modal.confirm
expect(assign_modal).to be_closed
expect(topic_page).to have_assigned(user: admin2, at_post: 2)
find(".timeline-controls .toggle-admin-menu").click
find(".topic-admin-close").click
expect(find("#post_3")).to have_content(
I18n.t("js.action_codes.closed.enabled", when: "just now"),
)
expect(page).to have_no_css("#post_4")
expect(page).to have_no_css("#topic .assigned-to")
end
it "can assign the previous assignee" do
visit "/t/#{topic.id}"
topic_page.click_assign_topic
assign_modal.assignee = admin2
assign_modal.confirm
expect(assign_modal).to be_closed
expect(topic_page).to have_assigned(user: admin2, at_post: 2)
find(".timeline-controls .toggle-admin-menu").click
find(".topic-admin-close").click
expect(find("#post_3")).to have_content(
I18n.t("js.action_codes.closed.enabled", when: "just now"),
)
expect(page).to have_no_css("#post_4")
expect(page).to have_no_css("#topic .assigned-to")
topic_page.click_assign_topic
assign_modal.assignee = admin2
assign_modal.confirm
expect(page).to have_no_css("#post_4")
expect(find("#topic .assigned-to")).to have_content(admin2.username)
end
context "when reassign_on_open is set to true" do
before { SiteSetting.reassign_on_open = true }
it "reassigns the topic on open" do
skip_on_ci!("Flaky test - reassigning topic on open")
visit "/t/#{topic.id}"
topic_page.click_assign_topic
assign_modal.assignee = admin2
assign_modal.confirm
expect(assign_modal).to be_closed
expect(topic_page).to have_assigned(user: admin2)
find(".timeline-controls .toggle-admin-menu").click
find(".topic-admin-close").click
expect(find("#post_3")).to have_content(
I18n.t("js.action_codes.closed.enabled", when: "just now"),
)
expect(page).to have_no_css("#post_4")
expect(page).to have_no_css("#topic .assigned-to")
find(".timeline-controls .toggle-admin-menu").click
find(".topic-admin-open").click
expect(find("#post_4")).to have_content(
I18n.t("js.action_codes.closed.disabled", when: "just now"),
)
expect(page).to have_no_css("#post_5")
try_until_success(reason: "Relies on MessageBus updates") do
expect(find("#topic .assigned-to")).to have_content(admin2.username)
end
end
end
end
end
end
end
end