diff --git a/app/assets/stylesheets/common/float-kit/d-toasts.scss b/app/assets/stylesheets/common/float-kit/d-toasts.scss index 6619ca13080..4ad05435dff 100644 --- a/app/assets/stylesheets/common/float-kit/d-toasts.scss +++ b/app/assets/stylesheets/common/float-kit/d-toasts.scss @@ -15,6 +15,9 @@ top: 5px; right: 5px; z-index: z("max"); + display: flex; + flex-direction: column; + gap: 5px 0; .mobile-view & { left: 5px; diff --git a/plugins/chat/assets/javascripts/discourse/components/chat-message.gjs b/plugins/chat/assets/javascripts/discourse/components/chat-message.gjs index 813413956fc..9f6d3707804 100644 --- a/plugins/chat/assets/javascripts/discourse/components/chat-message.gjs +++ b/plugins/chat/assets/javascripts/discourse/components/chat-message.gjs @@ -84,6 +84,7 @@ export default class ChatMessage extends Component { {{on "mouseenter" this.onMouseEnter passive=true}} {{on "mouseleave" this.onMouseLeave passive=true}} {{on "mousemove" this.onMouseMove passive=true}} + {{on "click" this.toggleCheckIfPossible passive=true}} {{ChatOnLongPress this.onLongPressStart this.onLongPressEnd @@ -193,6 +194,7 @@ export default class ChatMessage extends Component { @service chatThreadPane; @service chatChannelsManager; @service router; + @service toasts; @tracked isActive = false; @@ -278,10 +280,27 @@ export default class ChatMessage extends Component { recursiveExpand(this.args.message); } + @action + toggleCheckIfPossible(event) { + if (!this.pane.selectingMessages) { + return; + } + + if (event.shiftKey) { + this.messageInteractor.bulkSelect(!this.args.message.selected); + return; + } + + this.messageInteractor.select(!this.args.message.selected); + } + @action toggleChecked(event) { + event.stopPropagation(); + if (event.shiftKey) { this.messageInteractor.bulkSelect(event.target.checked); + return; } this.messageInteractor.select(event.target.checked); diff --git a/plugins/chat/assets/javascripts/discourse/components/chat/selection-manager.js b/plugins/chat/assets/javascripts/discourse/components/chat/selection-manager.gjs similarity index 65% rename from plugins/chat/assets/javascripts/discourse/components/chat/selection-manager.js rename to plugins/chat/assets/javascripts/discourse/components/chat/selection-manager.gjs index 089e1acd1bc..610dd1dfa2a 100644 --- a/plugins/chat/assets/javascripts/discourse/components/chat/selection-manager.js +++ b/plugins/chat/assets/javascripts/discourse/components/chat/selection-manager.gjs @@ -6,23 +6,62 @@ import { isTesting } from "discourse-common/config/environment"; import { popupAjaxError } from "discourse/lib/ajax-error"; import { inject as service } from "@ember/service"; import { bind } from "discourse-common/utils/decorators"; -import { tracked } from "@glimmer/tracking"; import ChatModalMoveMessageToChannel from "discourse/plugins/chat/discourse/components/chat/modal/move-message-to-channel"; +import DButton from "discourse/components/d-button"; +import not from "truth-helpers/helpers/not"; +import I18n from "I18n"; export default class ChatSelectionManager extends Component { + + @service("composer") topicComposer; @service router; @service modal; @service site; + @service toasts; @service("chat-api") api; - // NOTE: showCopySuccess is used to display the message which animates - // after a delay. The on-animation-end helper is not really usable in - // system specs because it fires straight away, so we use lastCopySuccessful - // with a data attr instead so it's not instantly mutated. - @tracked showCopySuccess = false; - @tracked lastCopySuccessful = false; - get enableMove() { return this.args.enableMove ?? false; } @@ -96,16 +135,17 @@ export default class ChatSelectionManager extends Component { @action async copyMessages() { try { - this.lastCopySuccessful = false; - this.showCopySuccess = false; - if (!isTesting()) { // clipboard API throws errors in tests await clipboardCopyAsync(this.generateQuote); - } - this.showCopySuccess = true; - this.lastCopySuccessful = true; + this.toasts.success({ + duration: 3000, + data: { + message: I18n.t("chat.quote.copy_success"), + }, + }); + } } catch (error) { popupAjaxError(error); } diff --git a/plugins/chat/assets/javascripts/discourse/components/chat/selection-manager.hbs b/plugins/chat/assets/javascripts/discourse/components/chat/selection-manager.hbs deleted file mode 100644 index ccae3ccd24b..00000000000 --- a/plugins/chat/assets/javascripts/discourse/components/chat/selection-manager.hbs +++ /dev/null @@ -1,51 +0,0 @@ -
-
- - - {{#if this.site.desktopView}} - - {{/if}} - - {{#if this.enableMove}} - - {{/if}} - - -
- - {{#if this.showCopySuccess}} - - {{i18n "chat.quote.copy_success"}} - - {{/if}} -
\ No newline at end of file diff --git a/plugins/chat/assets/javascripts/discourse/lib/chat-message-interactor.js b/plugins/chat/assets/javascripts/discourse/lib/chat-message-interactor.js index 5ef9ab528a0..88694b116cf 100644 --- a/plugins/chat/assets/javascripts/discourse/lib/chat-message-interactor.js +++ b/plugins/chat/assets/javascripts/discourse/lib/chat-message-interactor.js @@ -45,6 +45,7 @@ export default class ChatMessageInteractor { @service router; @service modal; @service capabilities; + @service toasts; @tracked message = null; @tracked context = null; @@ -166,6 +167,14 @@ export default class ChatMessageInteractor { icon: "link", }); + if (this.site.mobileView) { + buttons.push({ + id: "copyText", + name: I18n.t("chat.copy_text"), + icon: "clipboard", + }); + } + if (this.canEdit) { buttons.push({ id: "edit", @@ -237,6 +246,14 @@ export default class ChatMessageInteractor { } } + copyText() { + clipboardCopy(this.message.message); + this.toasts.success({ + duration: 3000, + data: { message: I18n.t("chat.text_copied") }, + }); + } + copyLink() { const { protocol, host } = window.location; const channelId = this.message.channel.id; @@ -251,6 +268,10 @@ export default class ChatMessageInteractor { url = url.indexOf("/") === 0 ? protocol + "//" + host + url : url; clipboardCopy(url); + this.toasts.success({ + duration: 3000, + data: { message: I18n.t("chat.link_copied") }, + }); } @action diff --git a/plugins/chat/config/locales/client.en.yml b/plugins/chat/config/locales/client.en.yml index 8c91d3149b6..5fea4b6a2d8 100644 --- a/plugins/chat/config/locales/client.en.yml +++ b/plugins/chat/config/locales/client.en.yml @@ -29,6 +29,8 @@ en: chat_users_count: "Chat users" chat: + text_copied: Text copied to clipboard + link_copied: Link copied to clipboard deleted_chat_username: deleted dates: time_tiny: "h:mm" @@ -241,6 +243,7 @@ en: reply: "Reply" edit: "Edit" copy_link: "Copy link" + copy_text: "Copy text" rebake_message: "Rebuild HTML" retry_staged_message: title: "Network error" diff --git a/plugins/chat/plugin.rb b/plugins/chat/plugin.rb index 0473e0a05f0..adbf8d11365 100644 --- a/plugins/chat/plugin.rb +++ b/plugins/chat/plugin.rb @@ -18,6 +18,7 @@ register_asset "stylesheets/mobile/index.scss", :mobile register_svg_icon "comments" register_svg_icon "comment-slash" register_svg_icon "lock" +register_svg_icon "clipboard" register_svg_icon "file-audio" register_svg_icon "file-video" register_svg_icon "file-image" diff --git a/plugins/chat/spec/system/chat_message/channel_spec.rb b/plugins/chat/spec/system/chat_message/channel_spec.rb index 5f3c6778ab8..eb056898fd6 100644 --- a/plugins/chat/spec/system/chat_message/channel_spec.rb +++ b/plugins/chat/spec/system/chat_message/channel_spec.rb @@ -6,8 +6,8 @@ RSpec.describe "Chat message - channel", type: :system do fab!(:message_1) { Fabricate(:chat_message, chat_channel: channel_1) } let(:cdp) { PageObjects::CDP.new } - let(:chat) { PageObjects::Pages::Chat.new } - let(:channel) { PageObjects::Pages::ChatChannel.new } + let(:chat_page) { PageObjects::Pages::Chat.new } + let(:channel_page) { PageObjects::Pages::ChatChannel.new } before do chat_system_bootstrap @@ -17,9 +17,9 @@ RSpec.describe "Chat message - channel", type: :system do context "when hovering a message" do it "adds an active class" do - chat.visit_channel(channel_1) + chat_page.visit_channel(channel_1) - channel.hover_message(message_1) + channel_page.hover_message(message_1) expect(page).to have_css( ".chat-channel[data-id='#{channel_1.id}'] .chat-message-container[data-id='#{message_1.id}'].-active", @@ -27,15 +27,39 @@ RSpec.describe "Chat message - channel", type: :system do end end + context "when copying text of a message" do + before { cdp.allow_clipboard } + + it "[mobile] copies the text of a single message", mobile: true do + chat_page.visit_channel(channel_1) + channel_page.click_composer # ensures we don't block on vibrate due to no action + + channel_page.messages.copy_text(message_1) + + expect(cdp.read_clipboard.chomp).to eq(message_1.message) + expect(PageObjects::Components::Toasts.new).to have_success(I18n.t("js.chat.text_copied")) + end + end + context "when copying link to a message" do before { cdp.allow_clipboard } it "copies the link to the message" do - chat.visit_channel(channel_1) + chat_page.visit_channel(channel_1) - channel.copy_link(message_1) + channel_page.messages.copy_link(message_1) expect(cdp.read_clipboard).to include("/chat/c/-/#{channel_1.id}/#{message_1.id}") + expect(PageObjects::Components::Toasts.new).to have_success(I18n.t("js.chat.link_copied")) + end + + it "[mobile] copies the link to the message", mobile: true do + chat_page.visit_channel(channel_1) + + channel_page.messages.copy_link(message_1) + + expect(cdp.read_clipboard).to include("/chat/c/-/#{channel_1.id}/#{message_1.id}") + expect(PageObjects::Components::Toasts.new).to have_success(I18n.t("js.chat.link_copied")) end context "when the message is part of a thread" do @@ -49,14 +73,26 @@ RSpec.describe "Chat message - channel", type: :system do ) end - it "copies the link to the message and not to the thread" do - chat.visit_channel(channel_1) + it "copies the link to the message" do + chat_page.visit_channel(channel_1) - channel.copy_link(thread_1.original_message) + channel_page.messages.copy_link(thread_1.original_message) expect(cdp.read_clipboard).to include( "/chat/c/-/#{channel_1.id}/#{thread_1.original_message.id}", ) + expect(PageObjects::Components::Toasts.new).to have_success(I18n.t("js.chat.link_copied")) + end + + it "[mobile] copies the link to the message", mobile: true do + chat_page.visit_channel(channel_1) + + channel_page.messages.copy_link(thread_1.original_message) + + expect(cdp.read_clipboard).to include( + "/chat/c/-/#{channel_1.id}/#{thread_1.original_message.id}", + ) + expect(PageObjects::Components::Toasts.new).to have_success(I18n.t("js.chat.link_copied")) end end end diff --git a/plugins/chat/spec/system/chat_message/thread_spec.rb b/plugins/chat/spec/system/chat_message/thread_spec.rb index 4fc2ab9c6ad..38e833839d3 100644 --- a/plugins/chat/spec/system/chat_message/thread_spec.rb +++ b/plugins/chat/spec/system/chat_message/thread_spec.rb @@ -8,6 +8,7 @@ RSpec.describe "Chat message - thread", type: :system do Fabricate(:chat_message, in_reply_to: message_1, use_service: true) end + let(:cdp) { PageObjects::CDP.new } let(:chat_page) { PageObjects::Pages::Chat.new } let(:thread_page) { PageObjects::Pages::ChatThread.new } @@ -29,6 +30,20 @@ RSpec.describe "Chat message - thread", type: :system do end end + context "when copying text of a message" do + before { cdp.allow_clipboard } + + it "[mobile] copies the text of a single message", mobile: true do + chat_page.visit_thread(thread_message_1.thread) + thread_page.click_composer # ensures we don't block on vibrate due to no action + + thread_page.messages.copy_text(thread_message_1) + + expect(cdp.read_clipboard.chomp).to eq(thread_message_1.message) + expect(PageObjects::Components::Toasts.new).to have_success(I18n.t("js.chat.text_copied")) + end + end + context "when copying link to a message" do let(:cdp) { PageObjects::CDP.new } @@ -37,11 +52,23 @@ RSpec.describe "Chat message - thread", type: :system do it "copies the link to the thread" do chat_page.visit_thread(thread_message_1.thread) - thread_page.copy_link(thread_message_1) + thread_page.messages.copy_link(thread_message_1) expect(cdp.read_clipboard).to include( "/chat/c/-/#{channel_1.id}/t/#{thread_message_1.thread.id}/#{thread_message_1.id}", ) + expect(PageObjects::Components::Toasts.new).to have_success(I18n.t("js.chat.link_copied")) + end + + it "[mobile] copies the link to the thread", mobile: true do + chat_page.visit_thread(thread_message_1.thread) + + thread_page.messages.copy_link(thread_message_1) + + expect(cdp.read_clipboard).to include( + "/chat/c/-/#{channel_1.id}/t/#{thread_message_1.thread.id}/#{thread_message_1.id}", + ) + expect(PageObjects::Components::Toasts.new).to have_success(I18n.t("js.chat.link_copied")) end end end diff --git a/plugins/chat/spec/system/deleted_message_spec.rb b/plugins/chat/spec/system/deleted_message_spec.rb index 3ed862558be..80375aab7c0 100644 --- a/plugins/chat/spec/system/deleted_message_spec.rb +++ b/plugins/chat/spec/system/deleted_message_spec.rb @@ -17,12 +17,12 @@ RSpec.describe "Deleted message", type: :system do context "when deleting a message" do it "shows as deleted" do chat_page.visit_channel(channel_1) - channel_page.send_message("aaaaaaaaaaaaaaaaaaaa") + channel_page.send_message expect(page).to have_css(".-persisted") last_message = find(".chat-message-container:last-child") - channel_page.delete_message(OpenStruct.new(id: last_message["data-id"])) + channel_page.messages.delete(OpenStruct.new(id: last_message["data-id"])) expect(channel_page.messages).to have_deleted_message( OpenStruct.new(id: last_message["data-id"]), @@ -39,7 +39,7 @@ RSpec.describe "Deleted message", type: :system do .find_by(user: current_user) .update!(last_read_message_id: message.id) chat_page.visit_channel(channel_1) - channel_page.delete_message(message) + channel_page.messages.delete(message) expect(channel_page.messages).to have_deleted_message(message, count: 1) sidebar_component.click_link(channel_2.name) expect(channel_page).to have_no_loading_skeleton @@ -67,7 +67,7 @@ RSpec.describe "Deleted message", type: :system do using_session(:tab_2) do |session| sign_in(other_user) chat_page.visit_channel(channel_1) - channel_page.delete_message(message) + channel_page.messages.delete(message) session.quit end @@ -88,10 +88,10 @@ RSpec.describe "Deleted message", type: :system do it "groups them" do chat_page.visit_channel(channel_1) - channel_page.delete_message(message_1) - channel_page.delete_message(message_3) - channel_page.delete_message(message_4) - channel_page.delete_message(message_6) + channel_page.messages.delete(message_1) + channel_page.messages.delete(message_3) + channel_page.messages.delete(message_4) + channel_page.messages.delete(message_6) expect(channel_page.messages).to have_deleted_messages(message_1, message_6) expect(channel_page.messages).to have_deleted_message(message_4, count: 2) @@ -147,15 +147,17 @@ RSpec.describe "Deleted message", type: :system do expect(open_thread.messages).to have_message(thread_id: thread_1.id, id: message_4.id) expect(open_thread.messages).to have_message(thread_id: thread_1.id, id: message_5.id) + open_thread.send_message + Chat::Publisher.publish_bulk_delete!( channel_1, [message_1.id, message_2.id, message_4.id, message_5.id].flatten, ) - expect(channel_page.messages).to have_no_message(id: message_1.id) expect(channel_page.messages).to have_deleted_message(message_2, count: 2) - expect(open_thread.messages).to have_no_message(thread_id: thread_1.id, id: message_4.id) expect(open_thread.messages).to have_deleted_message(message_5, count: 2) + expect(open_thread.messages).to have_no_message(thread_id: thread_1.id, id: message_4.id) + expect(channel_page.messages).to have_no_message(id: message_1.id) end end end diff --git a/plugins/chat/spec/system/flag_message_spec.rb b/plugins/chat/spec/system/flag_message_spec.rb index f42bada31f7..10659bd0dcf 100644 --- a/plugins/chat/spec/system/flag_message_spec.rb +++ b/plugins/chat/spec/system/flag_message_spec.rb @@ -19,7 +19,7 @@ RSpec.describe "Flag message", type: :system do it "allows to flag a message" do chat.visit_channel(category_channel_1) - channel.flag_message(message_1) + channel.messages.flag(message_1) expect(page).to have_css(".flag-modal") diff --git a/plugins/chat/spec/system/page_objects/chat/chat_channel.rb b/plugins/chat/spec/system/page_objects/chat/chat_channel.rb index 209089f4e27..275ffc744d3 100644 --- a/plugins/chat/spec/system/page_objects/chat/chat_channel.rb +++ b/plugins/chat/spec/system/page_objects/chat/chat_channel.rb @@ -96,44 +96,8 @@ module PageObjects find(".more-buttons").click end - def flag_message(message) - hover_message(message) - click_more_button - find("[data-value='flag']").click - end - - def copy_link(message) - hover_message(message) - click_more_button - find("[data-value='copyLink']").click - end - - def flag_message(message) - hover_message(message) - click_more_button - find("[data-value='flag']").click - end - - def delete_message(message) - hover_message(message) - click_more_button - find("[data-value='delete']").click - end - - def restore_message(message) - hover_message(message) - click_more_button - find("[data-value='restore']").click - end - - def open_edit_message(message) - hover_message(message) - click_more_button - find("[data-value='edit']").click - end - def edit_message(message, text = nil) - open_edit_message(message) + messages.edit(message) send_message(message.message + text) if text end diff --git a/plugins/chat/spec/system/page_objects/chat/chat_thread.rb b/plugins/chat/spec/system/page_objects/chat/chat_thread.rb index ef8d7fb696a..6dec29a6c7c 100644 --- a/plugins/chat/spec/system/page_objects/chat/chat_thread.rb +++ b/plugins/chat/spec/system/page_objects/chat/chat_thread.rb @@ -118,22 +118,6 @@ module PageObjects message_by_id(message.id).find(".chat-message-expand").click end - def copy_link(message) - expand_message_actions(message) - find("[data-value='copyLink']").click - end - - def delete_message(message) - expand_message_actions(message) - find("[data-value='delete']").click - end - - def restore_message(message) - expand_deleted_message(message) - expand_message_actions(message) - find("[data-value='restore']").click - end - def expand_message_actions(message) hover_message(message) click_more_button @@ -155,14 +139,8 @@ module PageObjects ".chat-thread .chat-messages-container .chat-message-container[data-id=\"#{id}\"]" end - def open_edit_message(message) - hover_message(message) - click_more_button - find("[data-value='edit']").click - end - def edit_message(message, text = nil) - open_edit_message(message) + messages.edit(message) send_message(message.message + text) if text end end diff --git a/plugins/chat/spec/system/page_objects/chat/components/message.rb b/plugins/chat/spec/system/page_objects/chat/components/message.rb index bc5472222a9..52e8745c37d 100644 --- a/plugins/chat/spec/system/page_objects/chat/components/message.rb +++ b/plugins/chat/spec/system/page_objects/chat/components/message.rb @@ -30,6 +30,16 @@ module PageObjects component.find(".chat-message-expand").click end + def secondary_action(action) + if page.has_css?("html.mobile-view", wait: 0) + component.click(delay: 0.4) + page.find(".chat-message-actions [data-id=\"#{action}\"]").click + else + open_more_menu + page.find("[data-value='#{action}']").click + end + end + def select(shift: false) if component[:class].include?("-selectable") message_selector = component.find(".chat-message-selector") @@ -43,7 +53,7 @@ module PageObjects end if page.has_css?("html.mobile-view", wait: 0) - component.click(delay: 0.6) + component.click(delay: 0.4) page.find(".chat-message-actions [data-id=\"select\"]").click else hover diff --git a/plugins/chat/spec/system/page_objects/chat/components/messages.rb b/plugins/chat/spec/system/page_objects/chat/components/messages.rb index a9a2aceed7a..a72fe146711 100644 --- a/plugins/chat/spec/system/page_objects/chat/components/messages.rb +++ b/plugins/chat/spec/system/page_objects/chat/components/messages.rb @@ -16,6 +16,35 @@ module PageObjects page.find(context) end + def flag(message) + find(message).secondary_action("flag") + end + + def copy_link(message) + find(message).secondary_action("copyLink") + end + + def copy_text(message) + find(message).secondary_action("copyText") + end + + def flag(message) + find(message).secondary_action("flag") + end + + def delete(message) + find(message).secondary_action("delete") + end + + def restore(message) + find(message).expand + find(message).secondary_action("restore") + end + + def edit(message) + find(message).secondary_action("edit") + end + def has_action?(action, **args) message = find(args) message.open_more_menu diff --git a/plugins/chat/spec/system/restore_message_spec.rb b/plugins/chat/spec/system/restore_message_spec.rb index ce04ab86634..ede9b5e0748 100644 --- a/plugins/chat/spec/system/restore_message_spec.rb +++ b/plugins/chat/spec/system/restore_message_spec.rb @@ -7,7 +7,7 @@ RSpec.describe "Restore message", type: :system do fab!(:channel_1) { Fabricate(:category_channel) } let(:chat_page) { PageObjects::Pages::Chat.new } - let(:chat_channel_page) { PageObjects::Pages::ChatChannel.new } + let(:channel_page) { PageObjects::Pages::ChatChannel.new } before do chat_system_bootstrap @@ -23,10 +23,10 @@ RSpec.describe "Restore message", type: :system do sign_in(regular_user) chat_page.visit_channel(channel_1) - chat_channel_page.delete_message(message_1) + channel_page.messages.delete(message_1) - expect(chat_channel_page.messages).to have_deleted_message(message_1, count: 1) - expect(chat_channel_page.messages).to have_action("restore", id: message_1.id) + expect(channel_page.messages).to have_deleted_message(message_1, count: 1) + expect(channel_page.messages).to have_action("restore", id: message_1.id) end it "can't be restored by another user" do @@ -38,12 +38,12 @@ RSpec.describe "Restore message", type: :system do using_session(:regular_user) do |session| sign_in(regular_user) chat_page.visit_channel(channel_1) - chat_channel_page.delete_message(message_1) + channel_page.messages.delete(message_1) session.quit end using_session(:another_user) do |session| - expect(chat_channel_page.messages).to have_no_message(id: message_1.id) + expect(channel_page.messages).to have_no_message(id: message_1.id) session.quit end end @@ -61,14 +61,14 @@ RSpec.describe "Restore message", type: :system do using_session(:admin_user) do |session| sign_in(admin_user) chat_page.visit_channel(channel_1) - chat_channel_page.delete_message(message_1) + channel_page.messages.delete(message_1) session.quit end using_session(:regular_user) do |session| - expect(chat_channel_page.messages).to have_deleted_message(message_1, count: 1) - chat_channel_page.messages.expand(id: message_1.id) - expect(chat_channel_page.messages).to have_no_action("restore", id: message_1.id) + expect(channel_page.messages).to have_deleted_message(message_1, count: 1) + channel_page.messages.expand(id: message_1.id) + expect(channel_page.messages).to have_no_action("restore", id: message_1.id) session.quit end end diff --git a/plugins/chat/spec/system/thread_list/full_page_spec.rb b/plugins/chat/spec/system/thread_list/full_page_spec.rb index 35f883da606..20086bd37d6 100644 --- a/plugins/chat/spec/system/thread_list/full_page_spec.rb +++ b/plugins/chat/spec/system/thread_list/full_page_spec.rb @@ -168,7 +168,7 @@ describe "Thread list in side panel | full page", type: :system do sign_in(other_user) chat_page.visit_thread(thread_1) expect(side_panel_page).to have_open_thread(thread_1) - thread_page.delete_message(thread_1.original_message) + thread_page.messages.delete(thread_1.original_message) session.quit end @@ -192,7 +192,7 @@ describe "Thread list in side panel | full page", type: :system do channel_page.expand_deleted_message(thread_1.original_message) channel_page.message_thread_indicator(thread_1.original_message).click expect(side_panel_page).to have_open_thread(thread_1) - thread_page.restore_message(thread_1.original_message) + thread_page.messages.restore(thread_1.original_message) session.quit end diff --git a/plugins/chat/spec/system/transcript_spec.rb b/plugins/chat/spec/system/transcript_spec.rb index d75e376e3cc..619eb661583 100644 --- a/plugins/chat/spec/system/transcript_spec.rb +++ b/plugins/chat/spec/system/transcript_spec.rb @@ -20,7 +20,9 @@ RSpec.describe "Quoting chat message transcripts", type: :system do messages = Array.wrap(messages) messages.each { |message| channel_page.messages.select(message) } channel_page.selection_management.copy - expect(page).to have_css(".chat-selection-management[data-last-copy-successful]") + expect(PageObjects::Components::Toasts.new).to have_success( + I18n.t("js.chat.quote.copy_success"), + ) clip_text = cdp.read_clipboard expect(clip_text.chomp).to eq(generate_transcript(messages, current_user)) clip_text diff --git a/plugins/chat/spec/system/uploads_spec.rb b/plugins/chat/spec/system/uploads_spec.rb index df81a99bff9..3181e96ca1a 100644 --- a/plugins/chat/spec/system/uploads_spec.rb +++ b/plugins/chat/spec/system/uploads_spec.rb @@ -112,7 +112,7 @@ describe "Uploading files in chat messages", type: :system do it "allows deleting uploads" do chat.visit_channel(channel_1) - channel_page.open_edit_message(message_2) + channel_page.messages.edit(message_2) find(".chat-composer-upload").hover find(".chat-composer-upload__remove-btn").click channel_page.click_send_message @@ -122,7 +122,7 @@ describe "Uploading files in chat messages", type: :system do it "allows adding more uploads" do chat.visit_channel(channel_1) - channel_page.open_edit_message(message_2) + channel_page.messages.edit(message_2) file_path = file_from_fixtures("logo.png", "images").path attach_file(file_path) do diff --git a/spec/system/page_objects/components/toasts.rb b/spec/system/page_objects/components/toasts.rb new file mode 100644 index 00000000000..0481e5196b3 --- /dev/null +++ b/spec/system/page_objects/components/toasts.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module PageObjects + module Components + class Toasts < PageObjects::Components::Base + def has_default?(message) + has_css?(".fk-d-default-toast", text: message) + end + + def has_success?(message) + has_css?(".fk-d-default-toast.-success", text: message) + end + + def has_warning?(message) + has_css?(".fk-d-default-toast.-warning", text: message) + end + + def has_info?(message) + has_css?(".fk-d-default-toast.-info", text: message) + end + + def has_error?(message) + has_css?(".fk-d-default-toast.-error", text: message) + end + end + end +end