2023-03-15 16:02:20 -04:00
|
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
|
|
RSpec.describe "AI Composer helper", type: :system, js: true do
|
2024-01-15 07:18:56 -05:00
|
|
|
|
fab!(:user) { Fabricate(:admin, refresh_auto_groups: true) }
|
2023-09-13 17:18:48 -04:00
|
|
|
|
fab!(:non_member_group) { Fabricate(:group) }
|
2023-03-15 16:02:20 -04:00
|
|
|
|
|
|
|
|
|
before do
|
|
|
|
|
Group.find_by(id: Group::AUTO_GROUPS[:admins]).add(user)
|
2024-06-19 17:01:35 -04:00
|
|
|
|
assign_fake_provider_to(:ai_helper_model)
|
2024-08-12 18:40:23 -04:00
|
|
|
|
SiteSetting.ai_helper_enabled = true
|
2023-03-15 16:02:20 -04:00
|
|
|
|
sign_in(user)
|
|
|
|
|
end
|
|
|
|
|
|
2023-11-27 07:33:31 -05:00
|
|
|
|
let(:input) { "The rain in spain stays mainly in the Plane." }
|
2023-03-15 16:02:20 -04:00
|
|
|
|
let(:composer) { PageObjects::Components::Composer.new }
|
2024-09-13 14:59:30 -04:00
|
|
|
|
let(:ai_helper_menu) { PageObjects::Components::AiComposerHelperMenu.new }
|
2023-08-24 20:49:24 -04:00
|
|
|
|
let(:diff_modal) { PageObjects::Modals::DiffModal.new }
|
2024-11-27 15:21:03 -05:00
|
|
|
|
let(:ai_suggestion_dropdown) { PageObjects::Components::AiSuggestionDropdown.new }
|
2024-09-13 14:59:30 -04:00
|
|
|
|
let(:toasts) { PageObjects::Components::Toasts.new }
|
|
|
|
|
|
2024-03-05 10:48:28 -05:00
|
|
|
|
fab!(:category)
|
2023-09-05 12:56:12 -04:00
|
|
|
|
fab!(:category_2) { Fabricate(:category) }
|
2023-09-01 20:10:58 -04:00
|
|
|
|
fab!(:video) { Fabricate(:tag) }
|
|
|
|
|
fab!(:music) { Fabricate(:tag) }
|
|
|
|
|
fab!(:cloud) { Fabricate(:tag) }
|
|
|
|
|
fab!(:feedback) { Fabricate(:tag) }
|
|
|
|
|
fab!(:review) { Fabricate(:tag) }
|
2023-03-15 16:02:20 -04:00
|
|
|
|
|
2024-09-13 14:59:30 -04:00
|
|
|
|
def trigger_composer_helper(content)
|
2023-08-23 13:35:40 -04:00
|
|
|
|
visit("/latest")
|
|
|
|
|
page.find("#create-topic").click
|
|
|
|
|
composer.fill_content(content)
|
2024-09-13 14:59:30 -04:00
|
|
|
|
composer.click_toolbar_button("ai-helper-trigger")
|
2023-08-23 13:35:40 -04:00
|
|
|
|
end
|
|
|
|
|
|
2024-09-13 14:59:30 -04:00
|
|
|
|
context "when triggering composer AI helper" do
|
|
|
|
|
it "shows the context menu when clicking the AI button in the composer toolbar" do
|
|
|
|
|
trigger_composer_helper(input)
|
|
|
|
|
expect(ai_helper_menu).to have_context_menu
|
2023-08-23 13:35:40 -04:00
|
|
|
|
end
|
|
|
|
|
|
2024-09-13 14:59:30 -04:00
|
|
|
|
it "shows a toast error when clicking the AI button without content" do
|
|
|
|
|
trigger_composer_helper("")
|
|
|
|
|
expect(ai_helper_menu).to have_no_context_menu
|
|
|
|
|
expect(toasts).to have_error(I18n.t("js.discourse_ai.ai_helper.no_content_error"))
|
2023-08-28 18:08:51 -04:00
|
|
|
|
end
|
|
|
|
|
|
2024-09-13 14:59:30 -04:00
|
|
|
|
it "shows prompt options in menu when AI button is clicked" do
|
|
|
|
|
trigger_composer_helper(input)
|
|
|
|
|
expect(ai_helper_menu).to be_showing_options
|
2024-03-04 16:33:31 -05:00
|
|
|
|
end
|
|
|
|
|
|
2023-09-25 14:12:54 -04:00
|
|
|
|
context "when using custom prompt" do
|
2023-11-27 07:33:31 -05:00
|
|
|
|
let(:mode) { CompletionPrompt::CUSTOM_PROMPT }
|
|
|
|
|
|
|
|
|
|
let(:custom_prompt_input) { "Translate to French" }
|
|
|
|
|
let(:custom_prompt_response) { "La pluie en Espagne reste principalement dans l'avion." }
|
2023-09-25 14:12:54 -04:00
|
|
|
|
|
|
|
|
|
it "shows custom prompt option" do
|
2024-09-13 14:59:30 -04:00
|
|
|
|
trigger_composer_helper(input)
|
|
|
|
|
expect(ai_helper_menu).to have_custom_prompt
|
2023-09-25 14:12:54 -04:00
|
|
|
|
end
|
|
|
|
|
|
2023-09-27 17:27:16 -04:00
|
|
|
|
it "enables the custom prompt button when input is filled" do
|
2024-09-13 14:59:30 -04:00
|
|
|
|
trigger_composer_helper(input)
|
|
|
|
|
expect(ai_helper_menu).to have_custom_prompt_button_disabled
|
|
|
|
|
ai_helper_menu.fill_custom_prompt(custom_prompt_input)
|
|
|
|
|
expect(ai_helper_menu).to have_custom_prompt_button_enabled
|
2023-09-25 14:12:54 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "replaces the composed message with AI generated content" do
|
2024-09-13 14:59:30 -04:00
|
|
|
|
trigger_composer_helper(input)
|
|
|
|
|
ai_helper_menu.fill_custom_prompt(custom_prompt_input)
|
2023-11-27 07:33:31 -05:00
|
|
|
|
|
2023-11-28 23:17:46 -05:00
|
|
|
|
DiscourseAi::Completions::Llm.with_prepared_responses([custom_prompt_response]) do
|
2024-09-13 14:59:30 -04:00
|
|
|
|
ai_helper_menu.click_custom_prompt_button
|
|
|
|
|
diff_modal.confirm_changes
|
2023-11-27 07:33:31 -05:00
|
|
|
|
wait_for { composer.composer_input.value == custom_prompt_response }
|
|
|
|
|
expect(composer.composer_input.value).to eq(custom_prompt_response)
|
|
|
|
|
end
|
2023-09-25 14:12:54 -04:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "when not a member of custom prompt group" do
|
2023-11-27 07:33:31 -05:00
|
|
|
|
let(:mode) { CompletionPrompt::CUSTOM_PROMPT }
|
2023-09-25 14:12:54 -04:00
|
|
|
|
before { SiteSetting.ai_helper_custom_prompts_allowed_groups = non_member_group.id.to_s }
|
|
|
|
|
|
|
|
|
|
it "does not show custom prompt option" do
|
2024-09-13 14:59:30 -04:00
|
|
|
|
trigger_composer_helper(input)
|
|
|
|
|
expect(ai_helper_menu).to have_no_custom_prompt
|
2023-09-25 14:12:54 -04:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2023-08-23 13:35:40 -04:00
|
|
|
|
context "when using translation mode" do
|
2023-11-27 07:33:31 -05:00
|
|
|
|
let(:mode) { CompletionPrompt::TRANSLATE }
|
|
|
|
|
|
|
|
|
|
let(:spanish_input) { "La lluvia en España se queda principalmente en el avión." }
|
2023-08-23 13:35:40 -04:00
|
|
|
|
|
|
|
|
|
it "replaces the composed message with AI generated content" do
|
2024-09-13 14:59:30 -04:00
|
|
|
|
trigger_composer_helper(spanish_input)
|
2023-08-23 13:35:40 -04:00
|
|
|
|
|
2023-11-28 23:17:46 -05:00
|
|
|
|
DiscourseAi::Completions::Llm.with_prepared_responses([input]) do
|
2024-09-13 14:59:30 -04:00
|
|
|
|
ai_helper_menu.select_helper_model(mode)
|
|
|
|
|
diff_modal.confirm_changes
|
2023-11-27 07:33:31 -05:00
|
|
|
|
wait_for { composer.composer_input.value == input }
|
|
|
|
|
expect(composer.composer_input.value).to eq(input)
|
|
|
|
|
end
|
2023-08-23 13:35:40 -04:00
|
|
|
|
end
|
|
|
|
|
|
2023-08-23 18:35:53 -04:00
|
|
|
|
it "reverts results when Ctrl/Cmd + Z is pressed on the keyboard" do
|
2024-09-13 14:59:30 -04:00
|
|
|
|
trigger_composer_helper(spanish_input)
|
2023-08-23 18:35:53 -04:00
|
|
|
|
|
2023-11-28 23:17:46 -05:00
|
|
|
|
DiscourseAi::Completions::Llm.with_prepared_responses([input]) do
|
2024-09-13 14:59:30 -04:00
|
|
|
|
ai_helper_menu.select_helper_model(mode)
|
|
|
|
|
diff_modal.confirm_changes
|
2023-11-27 07:33:31 -05:00
|
|
|
|
wait_for { composer.composer_input.value == input }
|
2024-09-13 14:59:30 -04:00
|
|
|
|
ai_helper_menu.press_undo_keys
|
2023-11-27 07:33:31 -05:00
|
|
|
|
expect(composer.composer_input.value).to eq(spanish_input)
|
|
|
|
|
end
|
2023-08-23 18:35:53 -04:00
|
|
|
|
end
|
|
|
|
|
|
2024-09-13 14:59:30 -04:00
|
|
|
|
it "shows the changes in a modal" do
|
|
|
|
|
trigger_composer_helper(spanish_input)
|
2023-08-24 20:49:24 -04:00
|
|
|
|
|
2023-11-28 23:17:46 -05:00
|
|
|
|
DiscourseAi::Completions::Llm.with_prepared_responses([input]) do
|
2024-09-13 14:59:30 -04:00
|
|
|
|
ai_helper_menu.select_helper_model(mode)
|
2023-08-24 20:49:24 -04:00
|
|
|
|
|
2023-11-27 07:33:31 -05:00
|
|
|
|
expect(diff_modal).to be_visible
|
|
|
|
|
expect(diff_modal.old_value).to eq(spanish_input.gsub(/[[:space:]]+/, " ").strip)
|
|
|
|
|
expect(diff_modal.new_value).to eq(
|
|
|
|
|
input.gsub(/[[:space:]]+/, " ").gsub(/[‘’]/, "'").gsub(/[“”]/, '"').strip,
|
|
|
|
|
)
|
|
|
|
|
diff_modal.confirm_changes
|
2024-09-13 14:59:30 -04:00
|
|
|
|
expect(ai_helper_menu).to have_no_context_menu
|
2023-11-27 07:33:31 -05:00
|
|
|
|
end
|
2023-08-28 18:08:51 -04:00
|
|
|
|
end
|
2024-08-16 13:08:58 -04:00
|
|
|
|
|
2024-09-13 14:59:30 -04:00
|
|
|
|
it "does not apply the changes when discard button is pressed in the modal" do
|
|
|
|
|
trigger_composer_helper(spanish_input)
|
2024-08-16 13:08:58 -04:00
|
|
|
|
DiscourseAi::Completions::Llm.with_prepared_responses([input]) do
|
2024-09-13 14:59:30 -04:00
|
|
|
|
ai_helper_menu.select_helper_model(mode)
|
2024-08-16 13:08:58 -04:00
|
|
|
|
expect(diff_modal).to be_visible
|
2024-09-13 14:59:30 -04:00
|
|
|
|
diff_modal.discard_changes
|
|
|
|
|
expect(ai_helper_menu).to have_no_context_menu
|
2024-08-16 13:08:58 -04:00
|
|
|
|
expect(composer.composer_input.value).to eq(spanish_input)
|
|
|
|
|
end
|
|
|
|
|
end
|
2023-08-23 13:35:40 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "when using the proofreading mode" do
|
2023-11-27 07:33:31 -05:00
|
|
|
|
let(:mode) { CompletionPrompt::PROOFREAD }
|
|
|
|
|
|
|
|
|
|
let(:proofread_text) { "The rain in Spain, stays mainly in the Plane." }
|
2023-08-23 13:35:40 -04:00
|
|
|
|
|
|
|
|
|
it "replaces the composed message with AI generated content" do
|
2024-09-13 14:59:30 -04:00
|
|
|
|
trigger_composer_helper(input)
|
2023-08-23 13:35:40 -04:00
|
|
|
|
|
2023-11-28 23:17:46 -05:00
|
|
|
|
DiscourseAi::Completions::Llm.with_prepared_responses([proofread_text]) do
|
2024-09-13 14:59:30 -04:00
|
|
|
|
ai_helper_menu.select_helper_model(mode)
|
|
|
|
|
diff_modal.confirm_changes
|
2023-11-27 07:33:31 -05:00
|
|
|
|
wait_for { composer.composer_input.value == proofread_text }
|
|
|
|
|
expect(composer.composer_input.value).to eq(proofread_text)
|
|
|
|
|
end
|
2023-08-23 13:35:40 -04:00
|
|
|
|
end
|
|
|
|
|
end
|
2023-08-29 12:45:53 -04:00
|
|
|
|
end
|
2023-08-23 13:35:40 -04:00
|
|
|
|
|
2023-08-29 12:45:53 -04:00
|
|
|
|
context "when suggesting titles with AI title suggester" do
|
2023-11-27 07:33:31 -05:00
|
|
|
|
let(:mode) { CompletionPrompt::GENERATE_TITLES }
|
|
|
|
|
|
|
|
|
|
let(:titles) do
|
2023-11-28 10:52:22 -05:00
|
|
|
|
"<item>Rainy Spain</item><item>Plane-Bound Delights</item><item>Mysterious Spain</item><item>Plane-Rain Chronicles</item><item>Unveiling Spain</item>"
|
2023-11-27 07:33:31 -05:00
|
|
|
|
end
|
2023-08-23 13:35:40 -04:00
|
|
|
|
|
2023-08-29 12:45:53 -04:00
|
|
|
|
it "opens a menu with title suggestions" do
|
|
|
|
|
visit("/latest")
|
|
|
|
|
page.find("#create-topic").click
|
2023-11-27 07:33:31 -05:00
|
|
|
|
composer.fill_content(input)
|
2023-11-28 23:17:46 -05:00
|
|
|
|
DiscourseAi::Completions::Llm.with_prepared_responses([titles]) do
|
2023-11-27 07:33:31 -05:00
|
|
|
|
ai_suggestion_dropdown.click_suggest_titles_button
|
2023-08-23 13:35:40 -04:00
|
|
|
|
|
2023-11-27 07:33:31 -05:00
|
|
|
|
wait_for { ai_suggestion_dropdown.has_dropdown? }
|
2023-08-23 13:35:40 -04:00
|
|
|
|
|
2023-11-27 07:33:31 -05:00
|
|
|
|
expect(ai_suggestion_dropdown).to have_dropdown
|
|
|
|
|
end
|
2023-08-29 12:45:53 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "replaces the topic title with the selected title" do
|
|
|
|
|
visit("/latest")
|
|
|
|
|
page.find("#create-topic").click
|
2023-11-27 07:33:31 -05:00
|
|
|
|
composer.fill_content(input)
|
2023-11-28 23:17:46 -05:00
|
|
|
|
DiscourseAi::Completions::Llm.with_prepared_responses([titles]) do
|
2023-11-27 07:33:31 -05:00
|
|
|
|
ai_suggestion_dropdown.click_suggest_titles_button
|
2023-08-29 12:45:53 -04:00
|
|
|
|
|
2023-11-27 07:33:31 -05:00
|
|
|
|
wait_for { ai_suggestion_dropdown.has_dropdown? }
|
2023-08-29 12:45:53 -04:00
|
|
|
|
|
2023-11-27 07:33:31 -05:00
|
|
|
|
ai_suggestion_dropdown.select_suggestion_by_value(1)
|
|
|
|
|
expected_title = "Plane-Bound Delights"
|
2023-08-29 12:45:53 -04:00
|
|
|
|
|
2023-11-27 07:33:31 -05:00
|
|
|
|
expect(find("#reply-title").value).to eq(expected_title)
|
|
|
|
|
end
|
2023-08-29 12:45:53 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "closes the menu when clicking outside" do
|
|
|
|
|
visit("/latest")
|
|
|
|
|
page.find("#create-topic").click
|
2023-11-27 07:33:31 -05:00
|
|
|
|
composer.fill_content(input)
|
2023-08-29 12:45:53 -04:00
|
|
|
|
|
2023-11-28 23:17:46 -05:00
|
|
|
|
DiscourseAi::Completions::Llm.with_prepared_responses([titles]) do
|
2023-11-27 07:33:31 -05:00
|
|
|
|
ai_suggestion_dropdown.click_suggest_titles_button
|
2023-08-29 12:45:53 -04:00
|
|
|
|
|
2023-11-27 07:33:31 -05:00
|
|
|
|
wait_for { ai_suggestion_dropdown.has_dropdown? }
|
|
|
|
|
|
|
|
|
|
find(".d-editor-preview").click
|
2023-08-29 12:45:53 -04:00
|
|
|
|
|
2023-11-27 07:33:31 -05:00
|
|
|
|
expect(ai_suggestion_dropdown).to have_no_dropdown
|
|
|
|
|
end
|
2023-09-01 20:10:58 -04:00
|
|
|
|
end
|
2023-09-06 15:20:08 -04:00
|
|
|
|
|
|
|
|
|
it "only shows trigger button if there is sufficient content in the composer" do
|
|
|
|
|
visit("/latest")
|
|
|
|
|
page.find("#create-topic").click
|
|
|
|
|
composer.fill_content("abc")
|
|
|
|
|
|
|
|
|
|
expect(ai_suggestion_dropdown).to have_no_suggestion_button
|
|
|
|
|
|
2023-11-27 07:33:31 -05:00
|
|
|
|
composer.fill_content(input)
|
2023-09-06 15:20:08 -04:00
|
|
|
|
expect(ai_suggestion_dropdown).to have_suggestion_button
|
|
|
|
|
end
|
2023-09-01 20:10:58 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "when suggesting the category with AI category suggester" do
|
2024-02-01 12:06:51 -05:00
|
|
|
|
before { SiteSetting.ai_embeddings_enabled = true }
|
2023-09-01 20:10:58 -04:00
|
|
|
|
|
|
|
|
|
it "updates the category with the suggested category" do
|
|
|
|
|
response =
|
|
|
|
|
Category
|
|
|
|
|
.take(3)
|
2024-11-27 15:21:03 -05:00
|
|
|
|
.map do |category|
|
|
|
|
|
{
|
|
|
|
|
id: category.id,
|
|
|
|
|
name: category.name,
|
|
|
|
|
slug: category.slug,
|
|
|
|
|
color: category.color,
|
|
|
|
|
score: rand(0.0...45.0),
|
|
|
|
|
topicCount: rand(1..3),
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
.sort_by { |h| h[:score] }
|
2023-09-01 20:10:58 -04:00
|
|
|
|
DiscourseAi::AiHelper::SemanticCategorizer.any_instance.stubs(:categories).returns(response)
|
|
|
|
|
visit("/latest")
|
|
|
|
|
page.find("#create-topic").click
|
2023-11-27 07:33:31 -05:00
|
|
|
|
composer.fill_content(input)
|
2023-09-01 20:10:58 -04:00
|
|
|
|
ai_suggestion_dropdown.click_suggest_category_button
|
|
|
|
|
wait_for { ai_suggestion_dropdown.has_dropdown? }
|
2023-09-06 12:46:03 -04:00
|
|
|
|
suggestion = category_2.name
|
2024-11-27 15:21:03 -05:00
|
|
|
|
ai_suggestion_dropdown.select_suggestion_by_name(suggestion)
|
2023-09-01 20:10:58 -04:00
|
|
|
|
category_selector = page.find(".category-chooser summary")
|
2023-09-06 12:46:03 -04:00
|
|
|
|
expect(category_selector["data-name"]).to eq(suggestion)
|
2023-09-01 20:10:58 -04:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "when suggesting the tags with AI tag suggester" do
|
2024-02-01 12:06:51 -05:00
|
|
|
|
before { SiteSetting.ai_embeddings_enabled = true }
|
2023-09-01 20:10:58 -04:00
|
|
|
|
|
|
|
|
|
it "updates the tag with the suggested tag" do
|
|
|
|
|
response =
|
|
|
|
|
Tag
|
|
|
|
|
.take(5)
|
|
|
|
|
.pluck(:name)
|
|
|
|
|
.map { |s| { name: s, score: rand(0.0...45.0) } }
|
|
|
|
|
.sort { |h| h[:score] }
|
|
|
|
|
DiscourseAi::AiHelper::SemanticCategorizer.any_instance.stubs(:tags).returns(response)
|
|
|
|
|
|
|
|
|
|
visit("/latest")
|
|
|
|
|
page.find("#create-topic").click
|
2023-11-27 07:33:31 -05:00
|
|
|
|
composer.fill_content(input)
|
2023-09-01 20:10:58 -04:00
|
|
|
|
|
|
|
|
|
ai_suggestion_dropdown.click_suggest_tags_button
|
|
|
|
|
|
|
|
|
|
wait_for { ai_suggestion_dropdown.has_dropdown? }
|
|
|
|
|
|
|
|
|
|
suggestion = ai_suggestion_dropdown.suggestion_name(0)
|
2023-09-05 12:56:12 -04:00
|
|
|
|
ai_suggestion_dropdown.select_suggestion_by_value(0)
|
2023-09-01 20:10:58 -04:00
|
|
|
|
tag_selector = page.find(".mini-tag-chooser summary")
|
|
|
|
|
|
|
|
|
|
expect(tag_selector["data-name"]).to eq(suggestion)
|
2023-08-23 13:35:40 -04:00
|
|
|
|
end
|
|
|
|
|
end
|
2023-09-13 17:18:48 -04:00
|
|
|
|
|
|
|
|
|
context "when AI helper is disabled" do
|
2023-11-27 07:33:31 -05:00
|
|
|
|
let(:mode) { CompletionPrompt::GENERATE_TITLES }
|
2024-08-12 18:40:23 -04:00
|
|
|
|
before { SiteSetting.ai_helper_enabled = false }
|
2023-09-13 17:18:48 -04:00
|
|
|
|
|
2024-09-13 14:59:30 -04:00
|
|
|
|
it "does not show the AI helper button in the composer toolbar" do
|
|
|
|
|
visit("/latest")
|
|
|
|
|
page.find("#create-topic").click
|
|
|
|
|
composer.fill_content(input)
|
|
|
|
|
expect(page).to have_no_css(".d-editor-button-bar button.ai-helper-trigger")
|
2023-09-13 17:18:48 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "does not trigger AI suggestion buttons" do
|
|
|
|
|
visit("/latest")
|
|
|
|
|
page.find("#create-topic").click
|
2023-11-27 07:33:31 -05:00
|
|
|
|
composer.fill_content(input)
|
2023-09-13 17:18:48 -04:00
|
|
|
|
expect(ai_suggestion_dropdown).to have_no_suggestion_button
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context "when user is not a member of AI helper allowed group" do
|
2023-11-27 07:33:31 -05:00
|
|
|
|
let(:mode) { CompletionPrompt::GENERATE_TITLES }
|
2024-08-12 18:40:23 -04:00
|
|
|
|
before { SiteSetting.composer_ai_helper_allowed_groups = non_member_group.id.to_s }
|
2023-09-13 17:18:48 -04:00
|
|
|
|
|
2024-09-13 14:59:30 -04:00
|
|
|
|
it "does not show the AI helper button in the composer toolbar" do
|
|
|
|
|
visit("/latest")
|
|
|
|
|
page.find("#create-topic").click
|
|
|
|
|
composer.fill_content(input)
|
|
|
|
|
expect(page).to have_no_css(".d-editor-button-bar button.ai-helper-trigger")
|
2023-09-13 17:18:48 -04:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it "does not trigger AI suggestion buttons" do
|
|
|
|
|
visit("/latest")
|
|
|
|
|
page.find("#create-topic").click
|
2023-11-27 07:33:31 -05:00
|
|
|
|
composer.fill_content(input)
|
2023-09-13 17:18:48 -04:00
|
|
|
|
expect(ai_suggestion_dropdown).to have_no_suggestion_button
|
|
|
|
|
end
|
|
|
|
|
end
|
2024-02-01 17:58:04 -05:00
|
|
|
|
|
|
|
|
|
context "when suggestion features are disabled" do
|
|
|
|
|
let(:mode) { CompletionPrompt::GENERATE_TITLES }
|
|
|
|
|
before { SiteSetting.ai_helper_enabled_features = "context_menu" }
|
|
|
|
|
|
|
|
|
|
it "does not show suggestion buttons in the composer" do
|
|
|
|
|
visit("/latest")
|
|
|
|
|
page.find("#create-topic").click
|
|
|
|
|
composer.fill_content(input)
|
|
|
|
|
expect(ai_suggestion_dropdown).to have_no_suggestion_button
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2024-09-13 14:59:30 -04:00
|
|
|
|
context "when composer helper feature is disabled" do
|
2024-02-01 17:58:04 -05:00
|
|
|
|
before { SiteSetting.ai_helper_enabled_features = "suggestions" }
|
|
|
|
|
|
2024-09-13 14:59:30 -04:00
|
|
|
|
it "does not show button in the composer toolbar" do
|
|
|
|
|
visit("/latest")
|
|
|
|
|
page.find("#create-topic").click
|
|
|
|
|
composer.fill_content(input)
|
|
|
|
|
expect(page).to have_no_css(".d-editor-button-bar button.ai-helper-trigger")
|
2024-02-01 17:58:04 -05:00
|
|
|
|
end
|
|
|
|
|
end
|
2024-09-16 17:00:41 -04:00
|
|
|
|
|
|
|
|
|
context "when triggering composer AI helper", mobile: true do
|
|
|
|
|
it "should close the composer helper before showing the diff modal" do
|
|
|
|
|
visit("/latest")
|
|
|
|
|
page.find("#create-topic").click
|
|
|
|
|
composer.fill_content(input)
|
|
|
|
|
composer.click_toolbar_button("ai-helper-trigger")
|
|
|
|
|
|
|
|
|
|
DiscourseAi::Completions::Llm.with_prepared_responses([input]) do
|
|
|
|
|
ai_helper_menu.select_helper_model(CompletionPrompt::TRANSLATE)
|
|
|
|
|
expect(ai_helper_menu).to have_no_context_menu
|
|
|
|
|
expect(diff_modal).to be_visible
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
2023-03-15 16:02:20 -04:00
|
|
|
|
end
|