DEV: Re-introduce proofreading specs (#1263)

Followup fe7e73a6a436795c053a611884431f663f4bdd27 and
1300cc8a36dc33870f0d3c81e1e1a21a93e1f1de

Reintroduces proofreader specs and unskips ones skipped when
streaming composer suggestions were added. We just need to make sure
the jobs run immediately in specs because the job is what sends the
MessageBus event to the UI.

Also adds a pageobject method to confirm a diff is shown
in the modal before pressing Confirm button.
This commit is contained in:
Martin Brennan 2025-04-16 11:11:43 +10:00 committed by GitHub
parent 0f34ce999f
commit b5d42f373b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 50 additions and 6 deletions

View File

@ -8,36 +8,42 @@ RSpec.describe "AI Composer Proofreading Features", type: :system, js: true do
before do before do
assign_fake_provider_to(:ai_helper_model) assign_fake_provider_to(:ai_helper_model)
SiteSetting.ai_helper_enabled = true SiteSetting.ai_helper_enabled = true
# This needs to be done because the streaming suggestions for composer
# happen in a background job, which sends the MessageBus event to the client.
Jobs.run_immediately!
sign_in(admin) sign_in(admin)
end end
let(:composer) { PageObjects::Components::Composer.new } let(:composer) { PageObjects::Components::Composer.new }
let(:rich) { composer.rich_editor }
let(:toasts) { PageObjects::Components::Toasts.new } let(:toasts) { PageObjects::Components::Toasts.new }
let(:diff_modal) { PageObjects::Modals::DiffModal.new } let(:diff_modal) { PageObjects::Modals::DiffModal.new }
let(:keyboard_shortcut) { [PLATFORM_KEY_MODIFIER, :alt, "p"] }
context "when triggering via keyboard shortcut" do context "when triggering via keyboard shortcut" do
it "proofreads selected text using" do it "proofreads selected text" do
skip("Message bus updates not appearing in tests")
visit "/new-topic" visit "/new-topic"
composer.fill_content("hello worldd !") composer.fill_content("hello worldd !")
composer.select_range(6, 12) composer.select_range(6, 12)
DiscourseAi::Completions::Llm.with_prepared_responses(["world"]) do DiscourseAi::Completions::Llm.with_prepared_responses(["world"]) do
composer.composer_input.send_keys([PLATFORM_KEY_MODIFIER, :alt, "p"]) composer.composer_input.send_keys(keyboard_shortcut)
expect(diff_modal).to have_diff("worldd", "world")
diff_modal.confirm_changes diff_modal.confirm_changes
expect(composer.composer_input.value).to eq("hello world !") expect(composer.composer_input.value).to eq("hello world !")
end end
end end
it "proofreads all text when nothing is selected" do it "proofreads all text when nothing is selected" do
skip("Message bus updates not appearing in tests")
visit "/new-topic" visit "/new-topic"
composer.fill_content("hello worrld") composer.fill_content("hello worrld")
# Simulate AI response # Simulate AI response
DiscourseAi::Completions::Llm.with_prepared_responses(["hello world"]) do DiscourseAi::Completions::Llm.with_prepared_responses(["hello world"]) do
composer.composer_input.send_keys([PLATFORM_KEY_MODIFIER, :alt, "p"]) composer.composer_input.send_keys(keyboard_shortcut)
expect(diff_modal).to have_diff("worrld", "world")
diff_modal.confirm_changes diff_modal.confirm_changes
expect(composer.composer_input.value).to eq("hello world") expect(composer.composer_input.value).to eq("hello world")
end end
@ -48,9 +54,42 @@ RSpec.describe "AI Composer Proofreading Features", type: :system, js: true do
# Simulate AI response # Simulate AI response
DiscourseAi::Completions::Llm.with_prepared_responses(["hello world"]) do DiscourseAi::Completions::Llm.with_prepared_responses(["hello world"]) do
composer.composer_input.send_keys([PLATFORM_KEY_MODIFIER, :alt, "p"]) composer.composer_input.send_keys(keyboard_shortcut)
expect(toasts).to have_error(I18n.t("js.discourse_ai.ai_helper.no_content_error")) expect(toasts).to have_error(I18n.t("js.discourse_ai.ai_helper.no_content_error"))
end end
end end
context "when using rich text editor" do
before { SiteSetting.rich_editor = true }
it "proofreads selected text and replaces it" do
visit "/new-topic"
expect(composer).to be_opened
composer.toggle_rich_editor
composer.type_content("hello worldd !")
# NOTE: The rich text editor cannot use select_range on the page object since it is
# a contenteditable element. It would be hard to make this generic enough to put in
# the page object, maybe at some point in the future we can refactor this.
execute_script(<<~JS, text)
const composer = document.querySelector("#reply-control .d-editor-input");
const startNode = composer.firstChild.firstChild;
composer.focus();
const range = document.createRange();
range.setStart(startNode, 6);
range.setEnd(startNode, 12);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
JS
DiscourseAi::Completions::Llm.with_prepared_responses(["world"]) do
composer.composer_input.send_keys(keyboard_shortcut)
expect(diff_modal).to have_diff("worldd", "world")
diff_modal.confirm_changes
expect(rich).to have_css("p", text: "hello world !")
end
end
end
end end
end end

View File

@ -22,6 +22,11 @@ module PageObjects
def new_value def new_value
find(".composer-ai-helper-modal__new-value").text find(".composer-ai-helper-modal__new-value").text
end end
def has_diff?(old_value, new_value)
has_css?(".inline-diff ins", text: new_value) &&
has_css?(".inline-diff del", text: old_value)
end
end end
end end
end end