From 72ccd229e953d2238ebf7864de4db471ec21c49d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20K=C3=BChn?= Date: Mon, 20 Mar 2023 13:04:48 +0000 Subject: [PATCH] [IMP] mail: improve message options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Message options always compact by default - when compact: "reaction", "reply", "favorite", "more" - "delete" is shown after "edit" - dropdown for "more" Task-2362261 closes odoo/odoo#116029 Signed-off-by: Alexandre KΓΌhn (aku) --- .../static/tests/discuss_patch_tests.js | 6 +- addons/mail/static/src/core_ui/message.js | 17 +++- addons/mail/static/src/core_ui/message.scss | 14 ++- addons/mail/static/src/core_ui/message.xml | 37 +++---- addons/mail/static/src/js/tours/mail.js | 7 +- .../static/tests/composer/composer_tests.js | 8 +- .../static/tests/crosstab/crosstab_tests.js | 3 +- .../static/tests/discuss/discuss_tests.js | 24 +++-- .../mail/static/tests/discuss/inbox_tests.js | 14 +-- .../static/tests/message/message_tests.js | 98 ++++++++++--------- 10 files changed, 134 insertions(+), 94 deletions(-) diff --git a/addons/im_livechat/static/tests/discuss_patch_tests.js b/addons/im_livechat/static/tests/discuss_patch_tests.js index 1a3f77520a8..f6808197703 100644 --- a/addons/im_livechat/static/tests/discuss_patch_tests.js +++ b/addons/im_livechat/static/tests/discuss_patch_tests.js @@ -43,7 +43,7 @@ QUnit.test("No reaction button", async (assert) => { const { openDiscuss } = await start(); await openDiscuss(channelId); await click(".o-mail-Message"); - assert.containsNone($, "i[aria-label='Add a Reaction']"); + assert.containsNone($, "[title='Add a Reaction']"); }); QUnit.test("No reply button", async (assert) => { @@ -62,7 +62,7 @@ QUnit.test("No reply button", async (assert) => { const { openDiscuss } = await start(); await openDiscuss(channelId); await click(".o-mail-Message"); - assert.containsNone($, "i[aria-label='Reply']"); + assert.containsNone($, "[title='Reply']"); }); QUnit.test("add livechat in the sidebar on visitor sending first message", async (assert) => { @@ -116,7 +116,7 @@ QUnit.test("reaction button should not be present on livechat", async (assert) = await insertText(".o-mail-Composer-input", "Test"); await click(".o-mail-Composer-send"); await click(".o-mail-Message"); - assert.containsNone($, ".i[title='Add a Reaction']"); + assert.containsNone($, "[title='Add a Reaction']"); }); QUnit.test("invite button should be present on livechat", async (assert) => { diff --git a/addons/mail/static/src/core_ui/message.js b/addons/mail/static/src/core_ui/message.js index 51b10a83ec6..bfbdf3bd197 100644 --- a/addons/mail/static/src/core_ui/message.js +++ b/addons/mail/static/src/core_ui/message.js @@ -29,6 +29,8 @@ import { MessageNotificationPopover } from "./message_notification_popover"; import { MessageSeenIndicator } from "./message_seen_indicator"; import { _t } from "@web/core/l10n/translation"; import { ActionSwiper } from "@web/core/action_swiper/action_swiper"; +import { Dropdown } from "@web/core/dropdown/dropdown"; +import { DropdownItem } from "@web/core/dropdown/dropdown_item"; import { hasTouch } from "@web/core/browser/feature_detection"; import { url } from "@web/core/utils/urls"; @@ -48,6 +50,8 @@ export class Message extends Component { ActionSwiper, AttachmentList, Composer, + Dropdown, + DropdownItem, LinkPreviewList, MessageInReply, MessageReactions, @@ -79,7 +83,7 @@ export class Message extends Component { isEditing: false, isHovered: false, isClicked: false, - isActionListSquashed: this.env.inChatWindow, + expandOptions: false, lastReadMoreIndex: 0, isReadMoreByIndex: new Map(), }); @@ -163,6 +167,10 @@ export class Message extends Component { return this.threadService.avatarUrl(this.message.author, this.props.message.originThread); } + get expandText() { + return _t("Expand"); + } + get message() { return this.props.message; } @@ -247,7 +255,12 @@ export class Message extends Component { } get isActive() { - return this.state.isHovered || this.state.isClicked || this.emojiPicker?.isOpen; + return ( + this.state.isHovered || + this.state.isClicked || + this.emojiPicker?.isOpen || + this.state.expandOptions + ); } get isAlignedRight() { diff --git a/addons/mail/static/src/core_ui/message.scss b/addons/mail/static/src/core_ui/message.scss index 0d8548d1b4a..a83ac0d08da 100644 --- a/addons/mail/static/src/core_ui/message.scss +++ b/addons/mail/static/src/core_ui/message.scss @@ -47,11 +47,19 @@ } .o-mail-Message-actions { - z-index: $o-mail-NavigableList-zIndex - 1; + z-index: $o-mail-NavigableList-zIndex - 2; - i:hover { - background-color: $o-gray-300; + &.o-expanded { + z-index: $o-mail-NavigableList-zIndex - 1; } + + button:hover, .focus { + background-color: $o-gray-300 !important; + } +} + +.o-mail-Message-moreMenu { + z-index: $o-mail-NavigableList-zIndex; } .o-mail-Message-starred { diff --git a/addons/mail/static/src/core_ui/message.xml b/addons/mail/static/src/core_ui/message.xml index 9542d0e897e..42affd3398f 100644 --- a/addons/mail/static/src/core_ui/message.xml +++ b/addons/mail/static/src/core_ui/message.xml @@ -134,33 +134,28 @@ 'mt-n3': env.inChatWindow, 'ms-2': env.inDiscussApp, 'invisible': !isActive, + 'o-expanded': state.expandOptions }" > -
- - - - - - - - - - + + + + + + + + + Mark as Read + Mark as Unread + Edit + Delete + +
diff --git a/addons/mail/static/src/js/tours/mail.js b/addons/mail/static/src/js/tours/mail.js index f39943bf615..c071502e5fa 100644 --- a/addons/mail/static/src/js/tours/mail.js +++ b/addons/mail/static/src/js/tours/mail.js @@ -61,7 +61,12 @@ registry.category("web_tour.tours").add("mail_tour", { position: "top", }, { - trigger: ".o-mail-Message i[aria-label='Mark as Todo']", + trigger: ".o-mail-Message [title='Expand']", + content: _t("Expand options"), + position: "top", + }, + { + trigger: ".o-mail-Message [title='Mark as Todo']", content: Markup( _t("Messages can be starred to remind you to check back later.") ), diff --git a/addons/mail/static/tests/composer/composer_tests.js b/addons/mail/static/tests/composer/composer_tests.js index 592a983ee93..86853e9481e 100644 --- a/addons/mail/static/tests/composer/composer_tests.js +++ b/addons/mail/static/tests/composer/composer_tests.js @@ -248,11 +248,11 @@ QUnit.test( await openDiscuss(channelId); await click("button[aria-label='Emojis']"); $(".o-mail-EmojiPicker-content")[0].scrollTop = 150; - await click("i[title='Add a Reaction']"); + await click("[title='Add a Reaction']"); $(".o-mail-EmojiPicker-content")[0].scrollTop = 200; await click("button[aria-label='Emojis']"); assert.strictEqual($(".o-mail-EmojiPicker-content")[0].scrollTop, 150); - await click("i[title='Add a Reaction']"); + await click("[title='Add a Reaction']"); assert.strictEqual($(".o-mail-EmojiPicker-content")[0].scrollTop, 200); } ); @@ -752,7 +752,7 @@ QUnit.test("composer: add an attachment in reply to message in history", async ( }); const { openDiscuss } = await start(); await openDiscuss("mail.box_history"); - await click("i[aria-label='Reply']"); + await click("[title='Reply']"); const file = await createFile({ content: "hello, world", contentType: "text/plain", @@ -849,7 +849,7 @@ QUnit.test("Replying on a channel should focus composer initially", async (asser }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click("i[aria-label='Reply']"); + await click("[title='Reply']"); assert.strictEqual(document.activeElement, $(".o-mail-Composer-input")[0]); }); diff --git a/addons/mail/static/tests/crosstab/crosstab_tests.js b/addons/mail/static/tests/crosstab/crosstab_tests.js index 6d1d513ebac..606580c171f 100644 --- a/addons/mail/static/tests/crosstab/crosstab_tests.js +++ b/addons/mail/static/tests/crosstab/crosstab_tests.js @@ -239,7 +239,8 @@ QUnit.test("Message delete notification", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(); - await click("i[aria-label='Mark as Todo']"); + await click("[title='Expand']"); + await click("[title='Mark as Todo']"); assert.containsOnce($, "button:contains(Inbox) .badge"); assert.containsOnce($, "button:contains(Starred) .badge"); pyEnv["bus.bus"]._sendone(pyEnv.currentPartnerId, "mail.message/delete", { diff --git a/addons/mail/static/tests/discuss/discuss_tests.js b/addons/mail/static/tests/discuss/discuss_tests.js index f5ea918291d..261a2feae6f 100644 --- a/addons/mail/static/tests/discuss/discuss_tests.js +++ b/addons/mail/static/tests/discuss/discuss_tests.js @@ -477,7 +477,7 @@ QUnit.test("reply to message from inbox (message linked to document)", async (as assert.containsOnce($, ".o-mail-Message"); assert.containsOnce($, ".o-mail-Message-header:contains(on Refactoring)"); - await click("i[aria-label='Reply']"); + await click("[title='Reply']"); assert.hasClass($(".o-mail-Message"), "o-selected"); assert.containsOnce($, ".o-mail-Composer"); assert.containsOnce($, ".o-mail-Composer-coreHeader:contains(on: Refactoring)"); @@ -507,7 +507,7 @@ QUnit.test("Can reply to starred message", async (assert) => { }, }); await openDiscuss("mail.box_starred"); - await click("i[aria-label='Reply']"); + await click("[title='Reply']"); assert.containsOnce($, ".o-mail-Composer-coreHeader:contains('RandomName')"); await insertText(".o-mail-Composer-input", "abc"); await click(".o-mail-Composer-send"); @@ -536,7 +536,7 @@ QUnit.test("Can reply to history message", async (assert) => { }, }); await openDiscuss("mail.box_history"); - await click("i[aria-label='Reply']"); + await click("[title='Reply']"); assert.containsOnce($, ".o-mail-Composer-coreHeader:contains('RandomName')"); await insertText(".o-mail-Composer-input", "abc"); await click(".o-mail-Composer-send"); @@ -786,10 +786,17 @@ QUnit.test("rendering of inbox message", async (assert) => { const $message = $(".o-mail-Message"); assert.containsOnce($message, ".o-mail-Message-header:contains(on Refactoring)"); assert.containsN($message, ".o-mail-Message-actions i", 4); - assert.containsOnce($message, "i[aria-label='Add a Reaction']"); - assert.containsOnce($message, "i[aria-label='Mark as Todo']"); - assert.containsOnce($message, "i[aria-label='Reply']"); - assert.containsOnce($message, "i[aria-label='Mark as Read']"); + assert.containsOnce($message, "[title='Add a Reaction']"); + assert.containsOnce($message, "[title='Reply']"); + assert.containsOnce($message, "[title='Mark as Todo']"); + assert.containsOnce($message, "[title='Expand']"); + await click("[title='Expand']"); + assert.containsN($message, ".o-mail-Message-actions i", 5); + assert.containsOnce($message, "[title='Add a Reaction']"); + assert.containsOnce($message, "[title='Reply']"); + assert.containsOnce($message, "[title='Mark as Todo']"); + assert.containsOnce($message, "[title='Expand']"); + assert.containsOnce($message, "[title='Mark as Read']"); }); QUnit.test('messages marked as read move to "History" mailbox', async (assert) => { @@ -878,7 +885,8 @@ QUnit.test( assert.hasClass($("button:contains(Inbox)"), "o-active"); assert.containsN($, ".o-mail-Message", 2); - await click(".o-mail-Message:contains(not empty 1) i[aria-label='Mark as Read']"); + await click(".o-mail-Message:contains(not empty 1) [title='Expand']"); + await click(".o-mail-Message:contains(not empty 1) [title='Mark as Read']"); assert.containsOnce($, ".o-mail-Message"); assert.containsOnce($, ".o-mail-Message:contains(not empty 2)"); diff --git a/addons/mail/static/tests/discuss/inbox_tests.js b/addons/mail/static/tests/discuss/inbox_tests.js index d45e0fea0ff..1f1d9ade656 100644 --- a/addons/mail/static/tests/discuss/inbox_tests.js +++ b/addons/mail/static/tests/discuss/inbox_tests.js @@ -33,9 +33,9 @@ QUnit.test("reply: discard on reply button toggle", async (assert) => { await openDiscuss(); assert.containsOnce($, ".o-mail-Message"); - await click("i[aria-label='Reply']"); + await click("[title='Reply']"); assert.containsOnce($, ".o-mail-Composer"); - await click("i[aria-label='Reply']"); + await click("[title='Reply']"); assert.containsNone($, ".o-mail-Composer"); }); @@ -59,7 +59,7 @@ QUnit.test("reply: discard on click away", async (assert) => { await openDiscuss(); assert.containsOnce($, ".o-mail-Message"); - await click("i[aria-label='Reply']"); + await click("[title='Reply']"); assert.containsOnce($, ".o-mail-Composer"); $(".o-mail-Composer-input")[0].click(); @@ -100,7 +100,7 @@ QUnit.test("reply: discard on pressing escape", async (assert) => { await openDiscuss(); assert.containsOnce($, ".o-mail-Message"); - await click(".o-mail-Message-actions i[aria-label='Reply']"); + await click(".o-mail-Message [title='Reply']"); assert.containsOnce($, ".o-mail-Composer"); // Escape on emoji picker does not stop replying @@ -153,7 +153,7 @@ QUnit.test( await openDiscuss(); assert.containsOnce($, ".o-mail-Message"); - await click("i[aria-label='Reply']"); + await click("[title='Reply']"); await insertText(".o-mail-Composer-input", "Test"); await click(".o-mail-Composer-send"); assert.verifySteps(["/mail/message/post"]); @@ -191,7 +191,7 @@ QUnit.test( await openDiscuss(); assert.containsOnce($, ".o-mail-Message"); - await click("i[aria-label='Reply']"); + await click("[title='Reply']"); assert.strictEqual($(".o-mail-Composer-send").text().trim(), "Send"); await insertText(".o-mail-Composer-input", "Test"); @@ -563,7 +563,7 @@ QUnit.test("reply: stop replying button click", async (assert) => { await openDiscuss(); assert.containsOnce($, ".o-mail-Message"); - await click("i[aria-label='Reply']"); + await click("[title='Reply']"); assert.containsOnce($, ".o-mail-Composer"); assert.containsOnce($, "i[title='Stop replying']"); diff --git a/addons/mail/static/tests/message/message_tests.js b/addons/mail/static/tests/message/message_tests.js index 6ffb3524211..38bf6f87ac1 100644 --- a/addons/mail/static/tests/message/message_tests.js +++ b/addons/mail/static/tests/message/message_tests.js @@ -37,7 +37,8 @@ QUnit.test("Start edition on click edit", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click(".o-mail-Message-actions i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); assert.containsOnce($, ".o-mail-Message-editable .o-mail-Composer"); assert.strictEqual($(".o-mail-Message-editable .o-mail-Composer-input").val(), "Hello world"); }); @@ -56,7 +57,8 @@ QUnit.test("Cursor is at end of composer input on edit", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click("i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); const textarea = $(".o-mail-Composer-input")[0]; const contentLength = textarea.value.length; assert.strictEqual(textarea.selectionStart, contentLength); @@ -78,7 +80,8 @@ QUnit.test("Stop edition on click cancel", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click(".o-mail-Message-actions i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); await click(".o-mail-Message a:contains('cancel')"); assert.containsNone($, ".o-mail-Message-editable .o-mail-Composer"); }); @@ -98,7 +101,8 @@ QUnit.test("Stop edition on press escape", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click(".o-mail-Message-actions i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); await afterNextRender(() => triggerHotkey("Escape", false)); assert.containsNone($, ".o-mail-Message-editable .o-mail-Composer"); }); @@ -118,7 +122,8 @@ QUnit.test("Stop edition on click save", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click(".o-mail-Message-actions i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); await click(".o-mail-Message a:contains('save')"); assert.containsNone($, ".o-mail-Message-editable .o-mail-Composer"); }); @@ -138,7 +143,8 @@ QUnit.test("Stop edition on press enter", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click(".o-mail-Message-actions i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); await afterNextRender(() => triggerHotkey("Enter", false)); assert.containsNone($, ".o-mail-Message-editable .o-mail-Composer"); }); @@ -158,7 +164,8 @@ QUnit.test("Stop edition on click away", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click(".o-mail-Message-actions i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); await afterNextRender(() => triggerEvent(document.body, ".o-mail-DiscussSidebar", "click")); assert.containsNone($, ".o-mail-Message-editable .o-mail-Composer"); }); @@ -178,7 +185,8 @@ QUnit.test("Do not stop edition on click away when clicking on emoji", async (as }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click(".o-mail-Message-actions i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); await click(".o-mail-Composer button[aria-label='Emojis']"); await click(".o-mail-EmojiPicker-content .o-mail-Emoji"); assert.containsOnce($, ".o-mail-Message-editable .o-mail-Composer"); @@ -199,7 +207,8 @@ QUnit.test("Edit and click save", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click(".o-mail-Message-actions i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); await editInput(document.body, ".o-mail-Message .o-mail-Composer-input", "Goodbye World"); await click(".o-mail-Message a:contains('save')"); assert.strictEqual($(".o-mail-Message-body")[0].innerText, "Goodbye World"); @@ -226,7 +235,8 @@ QUnit.test("Do not call server on save if no changes", async (assert) => { }, }); await openDiscuss(channelId); - await click(".o-mail-Message-actions i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); await click(".o-mail-Message a:contains('save')"); assert.verifySteps([]); }); @@ -246,7 +256,8 @@ QUnit.test("Scroll bar to the top when edit starts", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click(".o-mail-Message-actions i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); const $textarea = $(".o-mail-Composer-input"); assert.ok($textarea[0].scrollHeight > $textarea[0].clientHeight); assert.strictEqual($textarea[0].scrollTop, 0); @@ -265,7 +276,7 @@ QUnit.test("Other messages are grayed out when replying to another one", async ( const { openDiscuss } = await start(); await openDiscuss(channelId); assert.containsN($, ".o-mail-Message", 2); - await click(".o-mail-Message:contains(Hello world) i[aria-label='Reply']"); + await click(".o-mail-Message:contains(Hello world) [title='Reply']"); assert.doesNotHaveClass($(".o-mail-Message:contains(Hello world)"), "opacity-50"); assert.hasClass($(".o-mail-Message:contains(Goodbye world)"), "opacity-50"); }); @@ -283,7 +294,7 @@ QUnit.test("Parent message body is displayed on replies", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click(".o-mail-Message i[aria-label='Reply']"); + await click(".o-mail-Message [title='Reply']"); await editInput(document.body, ".o-mail-Composer-input", "FooBarFoo"); await click(".o-mail-Composer-send"); assert.containsOnce($, ".o-mail-MessageInReply-message"); @@ -306,10 +317,11 @@ QUnit.test( }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click("i[aria-label='Reply']"); + await click("[title='Reply']"); await editInput(document.body, ".o-mail-Composer-input", "FooBarFoo"); await triggerHotkey("Enter", false); - await click("i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); await editInput(document.body, ".o-mail-Message .o-mail-Composer-input", "Goodbye World"); await triggerHotkey("Enter", false); await nextTick(); @@ -331,10 +343,11 @@ QUnit.test("Deleting parent message of a reply should adapt reply visual", async }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click("i[aria-label='Reply']"); + await click("[title='Reply']"); await editInput(document.body, ".o-mail-Composer-input", "FooBarFoo"); await triggerHotkey("Enter", false); - await click("i[aria-label='Delete']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Delete']"); $('button:contains("Delete")').click(); await nextTick(); assert.containsOnce($, ".o-mail-MessageInReply:contains(Original message was deleted)"); @@ -354,9 +367,10 @@ QUnit.test("Can open emoji picker after edit mode", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click("i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); await triggerEvent(document.body, ".o-mail-DiscussSidebar", "click"); - await click("i[aria-label='Add a Reaction']"); + await click("[title='Add a Reaction']"); assert.containsOnce($, ".o-mail-EmojiPicker"); }); @@ -374,7 +388,7 @@ QUnit.test("Can add a reaction", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click("i[aria-label='Add a Reaction']"); + await click("[title='Add a Reaction']"); await click(".o-mail-Emoji:contains(πŸ˜…)"); assert.containsOnce($, ".o-mail-MessageReaction:contains('πŸ˜…')"); }); @@ -393,7 +407,7 @@ QUnit.test("Can remove a reaction", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click("i[aria-label='Add a Reaction']"); + await click("[title='Add a Reaction']"); await click(".o-mail-Emoji:contains(πŸ˜…)"); await click(".o-mail-MessageReaction"); assert.containsNone($, ".o-mail-MessageReaction:contains('πŸ˜…')"); @@ -457,7 +471,7 @@ QUnit.test("Reaction summary", async (assert) => { for (const [idx, name] of partnerNames.entries()) { const partnerId = pyEnv["res.partner"].create({ name }); pyEnv.currentPartnerId = partnerId; - await click("i[aria-label='Add a Reaction']"); + await click("[title='Add a Reaction']"); await click(".o-mail-Emoji:contains(πŸ˜…)"); assert.hasAttrValue($(".o-mail-MessageReaction")[0], "title", expectedSummaries[idx]); } @@ -477,9 +491,9 @@ QUnit.test("Add the same reaction twice from the emoji picker", async (assert) = }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click("i[aria-label='Add a Reaction']"); + await click("[title='Add a Reaction']"); await click(".o-mail-Emoji:contains(πŸ˜…)"); - await click("i[aria-label='Add a Reaction']"); + await click("[title='Add a Reaction']"); await click(".o-mail-Emoji:contains(πŸ˜…)"); assert.containsOnce($, ".o-mail-MessageReaction:contains('πŸ˜…')"); }); @@ -514,11 +528,6 @@ QUnit.test("basic rendering of message", async (assert) => { "title", deserializeDateTime("2019-04-20 10:00:00").toLocaleString(DateTime.DATETIME_SHORT) ); - assert.containsOnce($message, ".o-mail-Message-actions"); - assert.containsN($message, ".o-mail-Message-actions i", 4); - assert.containsOnce($message, "i[aria-label='Add a Reaction']"); - assert.containsOnce($message, "i[aria-label='Mark as Todo']"); - assert.containsOnce($message, "i[aria-label='Reply']"); assert.containsOnce($message, ".o-mail-Message-content"); assert.strictEqual($message.find(".o-mail-Message-content").text(), "body"); }); @@ -531,7 +540,7 @@ QUnit.test("should not be able to reply to temporary/transient messages", async // these user interactions is to forge a transient message response from channel command "/who" await insertText(".o-mail-Composer-input", "/who"); await click(".o-mail-Composer-send"); - assert.containsNone($, ".o-mail-Message i[aria-label='Reply']"); + assert.containsNone($, ".o-mail-Message [title='Reply']"); }); QUnit.test("message comment of same author within 1min. should be squashed", async (assert) => { @@ -622,23 +631,20 @@ QUnit.test("toggle_star message", async (assert) => { await openDiscuss(channelId); assert.containsNone($, "button:contains(Starred) .badge"); assert.containsOnce($, ".o-mail-Message"); - let $message = $(".o-mail-Message"); - assert.containsOnce($message, "i[aria-label='Mark as Todo']"); - assert.hasClass($message.find("i[aria-label='Mark as Todo']"), "fa-star-o"); + assert.containsOnce($, ".o-mail-Message [title='Mark as Todo']"); + assert.hasClass($(".o-mail-Message [title='Mark as Todo'] i"), "fa-star-o"); - await click("i[aria-label='Mark as Todo']"); + await click("[title='Mark as Todo']"); assert.verifySteps(["rpc:toggle_message_starred"]); assert.strictEqual($("button:contains(Starred) .badge").text(), "1"); assert.containsOnce($, ".o-mail-Message"); - $message = $(".o-mail-Message"); - assert.hasClass($message.find("i[aria-label='Mark as Todo']"), "fa-star"); + assert.hasClass($(".o-mail-Message [title='Mark as Todo'] i"), "fa-star"); - await click("i[aria-label='Mark as Todo']"); + await click("[title='Mark as Todo']"); assert.verifySteps(["rpc:toggle_message_starred"]); assert.containsNone($, "button:contains(Starred) .badge"); assert.containsOnce($, ".o-mail-Message"); - $message = $(".o-mail-Message"); - assert.hasClass($message.find("i[aria-label='Mark as Todo']"), "fa-star-o"); + assert.hasClass($(".o-mail-Message [title='Mark as Todo'] i"), "fa-star-o"); }); QUnit.test( @@ -705,7 +711,8 @@ QUnit.test("click on message edit button should open edit composer", async (asse }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click(".o-mail-Message-actions i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); assert.containsOnce($, ".o-mail-Message .o-mail-Composer"); }); @@ -834,7 +841,8 @@ QUnit.test( }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click(".o-mail-Message-actions i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); await editInput(document.body, ".o-mail-Message-editable .o-mail-Composer-input", ""); await afterNextRender(() => triggerHotkey("Enter")); assert.containsOnce( @@ -864,7 +872,8 @@ QUnit.test( }); const { openDiscuss } = await start(); await openDiscuss(channelId); - await click(".o-mail-Message-actions i[aria-label='Edit']"); + await click(".o-mail-Message [title='Expand']"); + await click(".o-mail-Message [title='Edit']"); await editInput(document.body, ".o-mail-Message-editable .o-mail-Composer-input", ""); await afterNextRender(() => triggerHotkey("Enter")); assert.containsNone( @@ -1003,7 +1012,7 @@ QUnit.test("Toggle star should update starred counter on all tabs", async (asser const tab2 = await start({ asTab: true }); await tab1.openDiscuss(channelId); await tab2.openDiscuss(); - await tab1.click("i[aria-label='Mark as Todo']"); + await tab1.click(".o-mail-Message [title='Mark as Todo']"); assert.strictEqual($(tab2.target).find("button:contains(Starred) .badge").text(), "1"); }); @@ -1383,7 +1392,7 @@ QUnit.test("Can reply to chatter messages from history", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss("mail.box_history"); - assert.containsOnce($, ".o-mail-Message-actions [title='Reply']"); + assert.containsOnce($, ".o-mail-Message [title='Reply']"); }); QUnit.test("Mark as unread", async (assert) => { @@ -1396,6 +1405,7 @@ QUnit.test("Mark as unread", async (assert) => { }); const { openDiscuss } = await start(); await openDiscuss(channelId); + await click("[title='Expand']"); await click("[title='Mark as Unread']"); assert.containsOnce($, ".o-mail-Thread-newMessage"); assert.containsOnce($, ".o-mail-DiscussCategoryItem .badge:contains(1)");