From 811f159f185a768cb49670f4162b092ba60afbfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Theys?= Date: Thu, 31 Aug 2023 17:39:34 +0200 Subject: [PATCH] [REF] mail, *: tests: replace remaining jQuery text() occurrences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * = im_livechat, snailmail, test_mail, website_livechat And also `innerText`. closes odoo/odoo#133717 Related: odoo/enterprise#46603 Signed-off-by: Alexandre Kühn (aku) --- .../static/tests/composer_patch_tests.js | 2 +- .../tests/activity/activity_menu_tests.js | 5 +- .../static/tests/activity/activity_tests.js | 5 +- .../tests/discuss/core/suggestion_tests.js | 8 +- .../core/web/chat_window_new_message_tests.js | 43 +- .../static/tests/discuss_app/discuss_tests.js | 17 +- .../discuss_app/jump_to_present_tests.js | 15 +- .../static/tests/discuss_app/sidebar_tests.js | 6 +- .../static/tests/message/message_tests.js | 22 +- .../messaging_menu/messaging_menu_tests.js | 86 ++- .../messaging_menu/notification_tests.js | 51 +- .../mail/static/tests/thread/thread_tests.js | 6 +- addons/mail/static/tests/web/chatter_tests.js | 5 +- .../static/tests/web/chatter_topbar_tests.js | 8 +- .../tests/web/fields/m2x_avatar_user_tests.js | 496 ++++++++---------- .../tests/web/follower_list_menu_tests.js | 13 +- .../tests/message/message_patch_tests.js | 107 +--- .../messaging_menu_patch_tests.js | 34 +- .../test_mail/static/tests/activity_tests.js | 40 +- .../tests/messaging_service_patch_tests.js | 23 +- 20 files changed, 381 insertions(+), 611 deletions(-) diff --git a/addons/im_livechat/static/tests/composer_patch_tests.js b/addons/im_livechat/static/tests/composer_patch_tests.js index 2a1804addc5..912e8b3a221 100644 --- a/addons/im_livechat/static/tests/composer_patch_tests.js +++ b/addons/im_livechat/static/tests/composer_patch_tests.js @@ -83,7 +83,7 @@ QUnit.test('Receives visitor typing status "is typing"', async (assert) => { }); const { env, openDiscuss } = await start(); await openDiscuss(channelId); - assert.strictEqual($(".o-discuss-Typing").text(), ""); + await contains(".o-discuss-Typing", { text: "" }); const channel = pyEnv["discuss.channel"].searchRead([["id", "=", channelId]])[0]; // simulate receive typing notification from livechat visitor "is typing" await afterNextRender(() => diff --git a/addons/mail/static/tests/activity/activity_menu_tests.js b/addons/mail/static/tests/activity/activity_menu_tests.js index d67ccc7d4b3..789cfe38a80 100644 --- a/addons/mail/static/tests/activity/activity_menu_tests.js +++ b/addons/mail/static/tests/activity/activity_menu_tests.js @@ -4,10 +4,11 @@ import { click, contains, start, startServer } from "@mail/../tests/helpers/test QUnit.module("activity menu"); -QUnit.test("should update activities when opening the activity menu", async (assert) => { +QUnit.test("should update activities when opening the activity menu", async () => { const pyEnv = await startServer(); await start(); - assert.strictEqual($(".o-mail-ActivityMenu-counter").text(), ""); + await contains(".o_menu_systray i[aria-label='Activities']"); + await contains(".o-mail-ActivityMenu-counter", { count: 0 }); const partnerId = pyEnv["res.partner"].create({}); pyEnv["mail.activity"].create({ res_id: partnerId, diff --git a/addons/mail/static/tests/activity/activity_tests.js b/addons/mail/static/tests/activity/activity_tests.js index 2a59434dbe2..2749ba13601 100644 --- a/addons/mail/static/tests/activity/activity_tests.js +++ b/addons/mail/static/tests/activity/activity_tests.js @@ -90,7 +90,7 @@ QUnit.test("activity simplest layout", async () => { await contains(".o-mail-Activity-info span", { count: 0, text: "Upload Document" }); }); -QUnit.test("activity with note layout", async (assert) => { +QUnit.test("activity with note layout", async () => { const pyEnv = await startServer(); const partnerId = pyEnv["res.partner"].create({}); pyEnv["mail.activity"].create({ @@ -101,8 +101,7 @@ QUnit.test("activity with note layout", async (assert) => { const { openFormView } = await start(); openFormView("res.partner", partnerId); await contains(".o-mail-Activity"); - await contains(".o-mail-Activity-note"); - assert.strictEqual($(".o-mail-Activity-note").text(), "There is no good or bad note"); + await contains(".o-mail-Activity-note", { text: "There is no good or bad note" }); }); QUnit.test("activity info layout when planned after tomorrow", async () => { diff --git a/addons/mail/static/tests/discuss/core/suggestion_tests.js b/addons/mail/static/tests/discuss/core/suggestion_tests.js index 1e7fba8ad21..4125c461886 100644 --- a/addons/mail/static/tests/discuss/core/suggestion_tests.js +++ b/addons/mail/static/tests/discuss/core/suggestion_tests.js @@ -62,7 +62,7 @@ QUnit.test("command suggestion should only open if command is the first characte await contains(".o-mail-Composer-suggestionList .o-open", { count: 0 }); }); -QUnit.test("Sort partner suggestions by recent chats", async (assert) => { +QUnit.test("Sort partner suggestions by recent chats", async () => { const pyEnv = await startServer(); const [partner_1, partner_2, partner_3] = pyEnv["res.partner"].create([ { name: "User 1" }, @@ -117,9 +117,9 @@ QUnit.test("Sort partner suggestions by recent chats", async (assert) => { await insertText(".o-mail-Composer-input[placeholder='Message #General…']", "@"); await insertText(".o-mail-Composer-input", "User"); await contains(".o-mail-Composer-suggestion strong", { count: 3 }); - assert.strictEqual($(".o-mail-Composer-suggestion").eq(0).text(), "User 2"); - assert.strictEqual($(".o-mail-Composer-suggestion").eq(1).text(), "User 1"); - assert.strictEqual($(".o-mail-Composer-suggestion").eq(2).text(), "User 3"); + await contains(".o-mail-Composer-suggestion:eq(0) strong", { text: "User 2" }); + await contains(".o-mail-Composer-suggestion:eq(1) strong", { text: "User 1" }); + await contains(".o-mail-Composer-suggestion:eq(2) strong", { text: "User 3" }); }); QUnit.test("mention suggestion are shown after deleting a character", async () => { diff --git a/addons/mail/static/tests/discuss/core/web/chat_window_new_message_tests.js b/addons/mail/static/tests/discuss/core/web/chat_window_new_message_tests.js index e0978e42e3d..e01231c40f3 100644 --- a/addons/mail/static/tests/discuss/core/web/chat_window_new_message_tests.js +++ b/addons/mail/static/tests/discuss/core/web/chat_window_new_message_tests.js @@ -7,16 +7,7 @@ import { } from "@mail/core/common/chat_window_service"; import { Command } from "@mail/../tests/helpers/command"; import { patchUiSize } from "@mail/../tests/helpers/patch_ui_size"; -import { - afterNextRender, - click, - contains, - insertText, - start, - startServer, -} from "@mail/../tests/helpers/test_utils"; - -import { makeDeferred } from "@web/../tests/helpers/utils"; +import { click, contains, insertText, start, startServer } from "@mail/../tests/helpers/test_utils"; QUnit.module("chat window: new message"); @@ -87,7 +78,6 @@ QUnit.test( ], }, ]); - const imSearchDef = makeDeferred(); patchUiSize({ width: 1920 }); assert.ok( CHAT_WINDOW_END_GAP_WIDTH * 2 + @@ -96,44 +86,23 @@ QUnit.test( 1920, "should have enough space to open 3 chat windows simultaneously" ); - await start({ - mockRPC(route, args) { - if (args.method === "im_search") { - imSearchDef.resolve(); - } - }, - }); + await start(); // open "new message" chat window await click(".o_menu_systray i[aria-label='Messages']"); await click("button", { text: "New Message" }); - await contains(".o-mail-ChatWindow-name", { text: "New message" }); await contains(".o-mail-ChatWindow", { count: 2 }); + await contains(".o-mail-ChatWindow-name:eq(1)", { text: "New message" }); await contains(".o-mail-ChatWindow .o-discuss-ChannelSelector"); - assert.ok( - Array.from(document.querySelectorAll(".o-mail-ChatWindow")) - .pop() - .textContent.includes("New message") - ); - // open channel-2 await click(".o_menu_systray i[aria-label='Messages']"); await click(".o-mail-NotificationItem-name", { text: "channel-2" }); await contains(".o-mail-ChatWindow", { count: 3 }); - assert.ok( - Array.from(document.querySelectorAll(".o-mail-ChatWindow"))[1].textContent.includes( - "New message" - ) - ); - + await contains(".o-mail-ChatWindow-name:eq(1)", { text: "New message" }); // search for a user in "new message" autocomplete - await afterNextRender(async () => { - await insertText(".o-discuss-ChannelSelector input", "131"); - await imSearchDef; - }); + await insertText(".o-discuss-ChannelSelector input", "131"); await click(".o-discuss-ChannelSelector-suggestion a", { text: "Partner 131" }); await contains(".o-mail-ChatWindow-name", { count: 0, text: "New message" }); - - assert.strictEqual($(".o-mail-ChatWindow-name:eq(1)").text(), "Partner 131"); + await contains(".o-mail-ChatWindow-name:eq(1)", { text: "Partner 131" }); } ); diff --git a/addons/mail/static/tests/discuss_app/discuss_tests.js b/addons/mail/static/tests/discuss_app/discuss_tests.js index d8f437bd9eb..d62dd62192f 100644 --- a/addons/mail/static/tests/discuss_app/discuss_tests.js +++ b/addons/mail/static/tests/discuss_app/discuss_tests.js @@ -833,24 +833,15 @@ QUnit.test("post a simple message", async (assert) => { text: "There are no messages in this conversation.", }); await contains(".o-mail-Message", { count: 0 }); - await contains(".o-mail-Composer-input", { value: "" }); - - // insert some HTML in editable await insertText(".o-mail-Composer-input", "Test"); - await contains(".o-mail-Composer-input", { value: "Test" }); - await click(".o-mail-Composer-send:not(:disabled)"); - await contains(".o-mail-Message"); - assert.verifySteps(["message_post"]); await contains(".o-mail-Composer-input", { value: "" }); - pyEnv["mail.message"].search([], { order: "id DESC" }); - const $message = $(".o-mail-Message"); + await contains(".o-mail-Message-author", { text: "Mitchell Admin" }); await contains(".o-mail-Message-content", { text: "Test" }); - assert.strictEqual($message.find(".o-mail-Message-author").text(), "Mitchell Admin"); - assert.strictEqual($message.find(".o-mail-Message-body").text(), "Test"); + assert.verifySteps(["message_post"]); }); -QUnit.test("starred: unstar all", async (assert) => { +QUnit.test("starred: unstar all", async () => { const pyEnv = await startServer(); pyEnv["mail.message"].create([ { body: "not empty", starred_partner_ids: [pyEnv.currentPartnerId] }, @@ -859,7 +850,7 @@ QUnit.test("starred: unstar all", async (assert) => { const { openDiscuss } = await start(); openDiscuss("mail.box_starred"); await contains(".o-mail-Message", { count: 2 }); - assert.strictEqual($("button:contains(Starred) .badge").text(), "2"); + await contains("button:contains(Starred) .badge", { text: "2" }); await click("button:contains(Unstar all):not(:disabled)"); await contains("button:contains(Starred) .badge", { count: 0 }); await contains(".o-mail-Message", { count: 0 }); diff --git a/addons/mail/static/tests/discuss_app/jump_to_present_tests.js b/addons/mail/static/tests/discuss_app/jump_to_present_tests.js index d71f93ff362..44e8c756700 100644 --- a/addons/mail/static/tests/discuss_app/jump_to_present_tests.js +++ b/addons/mail/static/tests/discuss_app/jump_to_present_tests.js @@ -44,7 +44,7 @@ QUnit.test("Basic jump to present when scrolling to outdated messages", async (a await contains(".o-mail-Thread", { scroll: "bottom" }); }); -QUnit.test("Jump to old reply should prompt jump to presence", async (assert) => { +QUnit.test("Jump to old reply should prompt jump to presence", async () => { // make scroll behavior instantaneous. patchWithCleanup(Element.prototype, { scrollIntoView() { @@ -84,21 +84,12 @@ QUnit.test("Jump to old reply should prompt jump to presence", async (assert) => await contains(".o-mail-Message", { count: 30 }); await click(".o-mail-MessageInReply .cursor-pointer"); await contains(".o-mail-Message", { count: 46 }); - assert.isVisible((await contains(".o-mail-Message:contains(Hello world!):eq(0)"))[0]); - assert.strictEqual( - $(".o-mail-Message-body:contains(Hello world!):eq(0)").text(), - "Hello world!", - "should correctly execute HTML tags in parent message when using 'load around' feature" - ); + await contains(".o-mail-Message-content:eq(0)", { text: "Hello world!" }); await contains(".o-mail-Thread-jumpPresent", { text: "You're viewing older messagesJump to Present", }); await click(".o-mail-Thread-jumpPresent"); - await contains(".o-mail-Thread-jumpPresent", { - count: 0, - text: "You're viewing older messagesJump to Present", - }); - + await contains(".o-mail-Thread-jumpPresent", { count: 0 }); await contains(".o-mail-Message", { count: 30 }); await contains(".o-mail-Thread", { scroll: "bottom" }); }); diff --git a/addons/mail/static/tests/discuss_app/sidebar_tests.js b/addons/mail/static/tests/discuss_app/sidebar_tests.js index 63c86ab0be8..1e398b0352b 100644 --- a/addons/mail/static/tests/discuss_app/sidebar_tests.js +++ b/addons/mail/static/tests/discuss_app/sidebar_tests.js @@ -309,7 +309,7 @@ QUnit.test("sidebar: unpin channel from bus", async () => { await contains(".o-mail-Discuss-threadName", { count: 0, value: "General" }); }); -QUnit.test("chat - channel should count unread message [REQUIRE FOCUS]", async (assert) => { +QUnit.test("chat - channel should count unread message [REQUIRE FOCUS]", async () => { const pyEnv = await startServer(); const partnerId = pyEnv["res.partner"].create({ name: "Demo", @@ -330,9 +330,7 @@ QUnit.test("chat - channel should count unread message [REQUIRE FOCUS]", async ( }); const { openDiscuss } = await start(); openDiscuss(); - await contains(".o-discuss-badge"); - assert.strictEqual($(".o-discuss-badge").text(), "1"); - + await contains(".o-discuss-badge", { text: "1" }); await click(".o-mail-DiscussSidebarChannel span", { text: "Demo" }); await contains(".o-discuss-badge", { count: 0 }); }); diff --git a/addons/mail/static/tests/message/message_tests.js b/addons/mail/static/tests/message/message_tests.js index cf2fbe9840b..085746ed678 100644 --- a/addons/mail/static/tests/message/message_tests.js +++ b/addons/mail/static/tests/message/message_tests.js @@ -372,7 +372,7 @@ QUnit.test("Other messages are grayed out when replying to another one", async ( }); }); -QUnit.test("Parent message body is displayed on replies", async (assert) => { +QUnit.test("Parent message body is displayed on replies", async () => { const pyEnv = await startServer(); const channelId = pyEnv["discuss.channel"].create({ channel_type: "channel", @@ -388,13 +388,12 @@ QUnit.test("Parent message body is displayed on replies", async (assert) => { await click(".o-mail-Message [title='Reply']"); await insertText(".o-mail-Composer-input", "FooBarFoo"); await click(".o-mail-Composer-send:not(:disabled)"); - await contains(".o-mail-MessageInReply-message"); - assert.ok($(".o-mail-MessageInReply-message")[0].innerText, "Hello world"); + await contains(".o-mail-MessageInReply-message", { text: "Hello world" }); }); QUnit.test( "Updating the parent message of a reply also updates the visual of the reply", - async (assert) => { + async () => { const pyEnv = await startServer(); const channelId = pyEnv["discuss.channel"].create({ channel_type: "channel", @@ -421,7 +420,6 @@ QUnit.test( insertText(input, "Goodbye World", { replace: true }); triggerHotkey("Enter", false); await contains(".o-mail-MessageInReply-message", { text: "Goodbye World" }); - assert.strictEqual($(".o-mail-MessageInReply-message")[0].innerText, "Goodbye World"); } ); @@ -765,7 +763,7 @@ QUnit.test("toggle_star message", async (assert) => { QUnit.test( "Name of message author is only displayed in chat window for partners others than the current user", - async (assert) => { + async () => { const pyEnv = await startServer(); const channelId = pyEnv["discuss.channel"].create({ channel_type: "channel" }); const partnerId = pyEnv["res.partner"].create({ name: "Not the current user" }); @@ -785,8 +783,7 @@ QUnit.test( await start(); await click(".o_menu_systray i[aria-label='Messages']"); await click(".o-mail-NotificationItem"); - await contains(".o-mail-Message-author"); - assert.equal($(".o-mail-Message-author").text(), "Not the current user"); + await contains(".o-mail-Message-author", { text: "Not the current user" }); } ); @@ -1047,7 +1044,7 @@ QUnit.test( } ); -QUnit.test("allow attachment delete on authored message", async (assert) => { +QUnit.test("allow attachment delete on authored message", async () => { const pyEnv = await startServer(); const channelId = pyEnv["discuss.channel"].create({ name: "test" }); pyEnv["mail.message"].create({ @@ -1071,13 +1068,8 @@ QUnit.test("allow attachment delete on authored message", async (assert) => { }); const { openDiscuss } = await start(); openDiscuss(channelId); - await contains(".o-mail-AttachmentImage"); - await contains(".o-mail-AttachmentImage div[title='Remove']"); - await click(".o-mail-AttachmentImage div[title='Remove']"); - await contains(".modal-dialog"); - assert.strictEqual($(".modal-body").text(), 'Do you really want to delete "BLAH"?'); - + await contains(".modal-dialog .modal-body", { text: 'Do you really want to delete "BLAH"?' }); await click(".modal-footer .btn-primary"); await contains(".o-mail-AttachmentCard", { count: 0 }); }); diff --git a/addons/mail/static/tests/messaging_menu/messaging_menu_tests.js b/addons/mail/static/tests/messaging_menu/messaging_menu_tests.js index c7663ce34c3..5703cdafe11 100644 --- a/addons/mail/static/tests/messaging_menu/messaging_menu_tests.js +++ b/addons/mail/static/tests/messaging_menu/messaging_menu_tests.js @@ -37,7 +37,7 @@ QUnit.test("messaging menu should have topbar buttons", async () => { await contains("button:contains(Channels).fw-bolder", { count: 0 }); }); -QUnit.test("counter is taking into account failure notification", async (assert) => { +QUnit.test("counter is taking into account failure notification", async () => { patchBrowserNotification("denied"); const pyEnv = await startServer(); const channelId = pyEnv["discuss.channel"].create({}); @@ -58,15 +58,14 @@ QUnit.test("counter is taking into account failure notification", async (assert) notification_type: "email", }); await start(); - await contains(".o-mail-MessagingMenu-counter"); - assert.strictEqual($(".o-mail-MessagingMenu-counter").text(), "1"); + await contains(".o-mail-MessagingMenu-counter", { text: "1" }); }); QUnit.test("rendering with OdooBot has a request (default)", async (assert) => { patchBrowserNotification("default"); await start(); await contains(".o-mail-MessagingMenu-counter"); - assert.strictEqual($(".o-mail-MessagingMenu-counter").text(), "1"); + await contains(".o-mail-MessagingMenu-counter", { text: "1" }); await click(".o_menu_systray i[aria-label='Messages']"); await contains(".o-mail-NotificationItem"); assert.ok( @@ -292,8 +291,8 @@ QUnit.test( await start(); await click(".o_menu_systray i[aria-label='Messages']"); await contains(".o-mail-NotificationItem", { count: 2 }); - assert.ok($(".o-mail-NotificationItem:eq(0)").text().includes("Company")); - assert.ok($(".o-mail-NotificationItem:eq(1)").text().includes("Partner")); + await contains(".o-mail-NotificationItem-name:eq(0)", { text: "Company" }); + await contains(".o-mail-NotificationItem-name:eq(1)", { text: "Partner" }); } ); @@ -818,46 +817,43 @@ QUnit.test( } ); -QUnit.test( - "single preview for channel if it has unread and needaction messages", - async (assert) => { - const pyEnv = await startServer(); - const partnerId = pyEnv["res.partner"].create({ name: "Partner1" }); - const channelId = pyEnv["discuss.channel"].create({ - name: "Test", - channel_member_ids: [ - Command.create({ message_unread_counter: 2, partner_id: pyEnv.currentPartnerId }), - ], - }); - const messageId = pyEnv["mail.message"].create({ - author_id: partnerId, - body: "Message with needaction", - model: "discuss.channel", - needaction: true, - needaction_partner_ids: [pyEnv.currentPartnerId], - res_id: channelId, - }); - pyEnv["mail.notification"].create({ - mail_message_id: messageId, - notification_status: "sent", - notification_type: "inbox", - res_partner_id: pyEnv.currentPartnerId, - }); - pyEnv["mail.message"].create({ - author_id: partnerId, - body: "Most-recent Message", - model: "discuss.channel", - res_id: channelId, - }); +QUnit.test("single preview for channel if it has unread and needaction messages", async () => { + const pyEnv = await startServer(); + const partnerId = pyEnv["res.partner"].create({ name: "Partner1" }); + const channelId = pyEnv["discuss.channel"].create({ + name: "Test", + channel_member_ids: [ + Command.create({ message_unread_counter: 2, partner_id: pyEnv.currentPartnerId }), + ], + }); + const messageId = pyEnv["mail.message"].create({ + author_id: partnerId, + body: "Message with needaction", + model: "discuss.channel", + needaction: true, + needaction_partner_ids: [pyEnv.currentPartnerId], + res_id: channelId, + }); + pyEnv["mail.notification"].create({ + mail_message_id: messageId, + notification_status: "sent", + notification_type: "inbox", + res_partner_id: pyEnv.currentPartnerId, + }); + pyEnv["mail.message"].create({ + author_id: partnerId, + body: "Most-recent Message", + model: "discuss.channel", + res_id: channelId, + }); - await start(); - await click(".o_menu_systray i[aria-label='Messages']"); - await contains(".o-mail-NotificationItem"); - assert.ok($(".o-mail-NotificationItem").text().includes("Test")); - assert.ok($(".o-mail-NotificationItem .badge").text().includes("1")); - assert.ok($(".o-mail-NotificationItem").text().includes("Message with needaction")); - } -); + await start(); + await click(".o_menu_systray i[aria-label='Messages']"); + await contains(".o-mail-NotificationItem"); + await contains(".o-mail-NotificationItem-name", { text: "Test" }); + await contains(".o-mail-NotificationItem .badge", { text: "1" }); + await contains(".o-mail-NotificationItem-text", { text: "Partner1: Message with needaction" }); +}); QUnit.test("chat should show unread counter on receiving new messages", async () => { // unread and needaction are conceptually the same in chat diff --git a/addons/mail/static/tests/messaging_menu/notification_tests.js b/addons/mail/static/tests/messaging_menu/notification_tests.js index bafcc2449e4..9dc9c531f4f 100644 --- a/addons/mail/static/tests/messaging_menu/notification_tests.js +++ b/addons/mail/static/tests/messaging_menu/notification_tests.js @@ -236,33 +236,30 @@ QUnit.test("non-failure notifications are ignored", async () => { await contains(".o-mail-NotificationItem", { count: 0 }); }); -QUnit.test( - "marked as read thread notifications are ordered by last message date", - async (assert) => { - const pyEnv = await startServer(); - const [channelId_1, channelId_2] = pyEnv["discuss.channel"].create([ - { name: "Channel 2019" }, - { name: "Channel 2020" }, - ]); - pyEnv["mail.message"].create([ - { - date: "2019-01-01 00:00:00", - model: "discuss.channel", - res_id: channelId_1, - }, - { - date: "2020-01-01 00:00:00", - model: "discuss.channel", - res_id: channelId_2, - }, - ]); - await start(); - await click(".o_menu_systray i[aria-label='Messages']"); - await contains(".o-mail-NotificationItem-name", { count: 2 }); - assert.strictEqual($(".o-mail-NotificationItem-name:eq(0)").text(), "Channel 2020"); - assert.strictEqual($(".o-mail-NotificationItem-name:eq(1)").text(), "Channel 2019"); - } -); +QUnit.test("marked as read thread notifications are ordered by last message date", async () => { + const pyEnv = await startServer(); + const [channelId_1, channelId_2] = pyEnv["discuss.channel"].create([ + { name: "Channel 2019" }, + { name: "Channel 2020" }, + ]); + pyEnv["mail.message"].create([ + { + date: "2019-01-01 00:00:00", + model: "discuss.channel", + res_id: channelId_1, + }, + { + date: "2020-01-01 00:00:00", + model: "discuss.channel", + res_id: channelId_2, + }, + ]); + await start(); + await click(".o_menu_systray i[aria-label='Messages']"); + await contains(".o-mail-NotificationItem-name", { count: 2 }); + await contains(".o-mail-NotificationItem-name:eq(0)", { text: "Channel 2020" }); + await contains(".o-mail-NotificationItem-name:eq(1)", { text: "Channel 2019" }); +}); QUnit.test("thread notifications are re-ordered on receiving a new message", async () => { const pyEnv = await startServer(); diff --git a/addons/mail/static/tests/thread/thread_tests.js b/addons/mail/static/tests/thread/thread_tests.js index b052bd06ea2..54e31b9c0da 100644 --- a/addons/mail/static/tests/thread/thread_tests.js +++ b/addons/mail/static/tests/thread/thread_tests.js @@ -1023,7 +1023,7 @@ QUnit.test("New message separator not appearing after showing composer on thread await contains(".o-mail-Thread-newMessage", { count: 0 }); }); -QUnit.test("Transient messages are added at the end of the thread", async (assert) => { +QUnit.test("Transient messages are added at the end of the thread", async () => { const pyEnv = await startServer(); const channelId = pyEnv["discuss.channel"].create({ name: "General" }); const { openDiscuss } = await start(); @@ -1034,6 +1034,6 @@ QUnit.test("Transient messages are added at the end of the thread", async (asser await insertText(".o-mail-Composer-input", "/help"); await click(".o-mail-Composer-send:not(:disabled)"); await contains(".o-mail-Message", { count: 2 }); - const lastMessage = document.querySelectorAll(".o-mail-Message")[1]; - assert.ok(lastMessage.innerText.includes("You are in channel #General")); + await contains(".o-mail-Message-author:eq(0)", { text: "Mitchell Admin" }); + await contains(".o-mail-Message-author:eq(1)", { text: "OdooBot" }); }); diff --git a/addons/mail/static/tests/web/chatter_tests.js b/addons/mail/static/tests/web/chatter_tests.js index 4bc262bca6a..87fa72f0fd0 100644 --- a/addons/mail/static/tests/web/chatter_tests.js +++ b/addons/mail/static/tests/web/chatter_tests.js @@ -311,7 +311,7 @@ QUnit.test("base rendering when chatter has no attachment", async (assert) => { await contains(".o-mail-Message", { count: 30 }); }); -QUnit.test("base rendering when chatter has no record", async (assert) => { +QUnit.test("base rendering when chatter has no record", async () => { const { openView } = await start(); openView({ res_model: "res.partner", @@ -322,9 +322,8 @@ QUnit.test("base rendering when chatter has no record", async (assert) => { await contains(".o-mail-AttachmentBox", { count: 0 }); await contains(".o-mail-Chatter .o-mail-Thread"); await contains(".o-mail-Message"); - assert.strictEqual($(".o-mail-Message-body").text(), "Creating a new record..."); + await contains(".o-mail-Message-body", { text: "Creating a new record..." }); await contains("button", { count: 0, text: "Load More" }); - await contains(".o-mail-Message-actions"); await contains(".o-mail-Message-actions i", { count: 0 }); }); diff --git a/addons/mail/static/tests/web/chatter_topbar_tests.js b/addons/mail/static/tests/web/chatter_topbar_tests.js index b9ebe1c70e4..4b249b29c97 100644 --- a/addons/mail/static/tests/web/chatter_topbar_tests.js +++ b/addons/mail/static/tests/web/chatter_topbar_tests.js @@ -30,7 +30,7 @@ QUnit.test("base rendering", async () => { await contains(".o-mail-Followers"); }); -QUnit.test("rendering with multiple partner followers", async (assert) => { +QUnit.test("rendering with multiple partner followers", async () => { const pyEnv = await startServer(); const [partnerId_1, partnerId_2, partnerId_3] = pyEnv["res.partner"].create([ { name: "Eden Hazard" }, @@ -55,15 +55,13 @@ QUnit.test("rendering with multiple partner followers", async (assert) => { res_model: "res.partner", views: [[false, "form"]], }); - await contains(".o-mail-Followers"); await contains(".o-mail-Followers-button"); - await click(".o-mail-Followers-button"); await contains(".o-mail-Followers-dropdown"); await contains(".o-mail-Follower", { count: 2 }); - assert.strictEqual($(".o-mail-Follower:eq(0)").text().trim(), "Jean Michang"); - assert.strictEqual($(".o-mail-Follower:eq(1)").text().trim(), "Eden Hazard"); + await contains(".o-mail-Follower:eq(0)", { text: "Jean Michang" }); + await contains(".o-mail-Follower:eq(1)", { text: "Eden Hazard" }); }); QUnit.test("log note toggling", async () => { diff --git a/addons/mail/static/tests/web/fields/m2x_avatar_user_tests.js b/addons/mail/static/tests/web/fields/m2x_avatar_user_tests.js index f6afc1f1542..c7245a72e92 100644 --- a/addons/mail/static/tests/web/fields/m2x_avatar_user_tests.js +++ b/addons/mail/static/tests/web/fields/m2x_avatar_user_tests.js @@ -1,16 +1,13 @@ /* @odoo-module */ -import { contains, start, startServer } from "@mail/../tests/helpers/test_utils"; +import { click, contains, start, startServer } from "@mail/../tests/helpers/test_utils"; import { - click, patchWithCleanup, triggerHotkey, triggerEvent, getNodesTextContent, } from "@web/../tests/helpers/utils"; import { registry } from "@web/core/registry"; -import { session } from "@web/session"; -import { nextTick } from "@web/../tests/legacy/helpers/test_utils"; import { popoverService } from "@web/core/popover/popover_service"; import { tooltipService } from "@web/core/tooltip/tooltip_service"; import { browser } from "@web/core/browser/browser"; @@ -47,7 +44,7 @@ const fakeImStatusService = { QUnit.module("M2XAvatarUser"); -QUnit.test("many2many_avatar_user in kanban view", async (assert) => { +QUnit.test("many2many_avatar_user in kanban view", async () => { const pyEnv = await startServer(); const userIds = pyEnv["res.users"].create([ { name: "Mario" }, @@ -82,249 +79,184 @@ QUnit.test("many2many_avatar_user in kanban view", async (assert) => { res_model: "m2x.avatar.user", views: [[false, "kanban"]], }); - await contains(".o_kanban_record .o_field_many2many_avatar_user .o_m2m_avatar_empty"); - assert.strictEqual( - $( - ".o_kanban_record .o_field_many2many_avatar_user .o_m2m_avatar_empty" - )[0].innerText.trim(), - "+2" - ); - await click( - document.querySelector( - ".o_kanban_record .o_field_many2many_avatar_user .o_m2m_avatar_empty" - ) - ); - const tags = document.querySelectorAll(".o_popover > .o_field_tags > .o_tag"); - assert.strictEqual(tags.length, 4); - assert.strictEqual(tags[0].innerText.trim(), "Tapu"); - assert.strictEqual(tags[1].innerText.trim(), "Luigi"); - assert.strictEqual(tags[2].innerText.trim(), "Yoshi"); - assert.strictEqual(tags[3].innerText.trim(), "Mario"); + await click(".o_kanban_record .o_field_many2many_avatar_user .o_m2m_avatar_empty", { + text: "+2", + }); + await click(".o_kanban_record .o_field_many2many_avatar_user .o_m2m_avatar_empty"); + await contains(".o_popover > .o_field_tags > .o_tag", { count: 4 }); + await contains(".o_popover > .o_field_tags > .o_tag:eq(0)", { text: "Tapu" }); + await contains(".o_popover > .o_field_tags > .o_tag:eq(1)", { text: "Luigi" }); + await contains(".o_popover > .o_field_tags > .o_tag:eq(2)", { text: "Yoshi" }); + await contains(".o_popover > .o_field_tags > .o_tag:eq(3)", { text: "Mario" }); }); -QUnit.test( - 'many2one_avatar_user widget edited by the smart action "Assign to..."', - async (assert) => { - const pyEnv = await startServer(); - const [userId_1] = pyEnv["res.users"].create([ - { name: "Mario" }, - { name: "Luigi" }, - { name: "Yoshi" }, - ]); - const avatarUserId_1 = pyEnv["m2x.avatar.user"].create({ user_id: userId_1 }); - const views = { - "m2x.avatar.user,false,form": - '
', - }; - const { openView } = await start({ serverData: { views } }); - await openView({ - res_id: avatarUserId_1, - type: "ir.actions.act_window", - target: "current", - res_model: "m2x.avatar.user", - view_mode: "form", - views: [[false, "form"]], - }); - await contains(".o_field_many2one_avatar_user input", { value: "Mario" }); +QUnit.test('many2one_avatar_user widget edited by the smart action "Assign to..."', async () => { + const pyEnv = await startServer(); + const [userId_1] = pyEnv["res.users"].create([ + { name: "Mario" }, + { name: "Luigi" }, + { name: "Yoshi" }, + ]); + const avatarUserId_1 = pyEnv["m2x.avatar.user"].create({ user_id: userId_1 }); + const views = { + "m2x.avatar.user,false,form": + '
', + }; + const { openView } = await start({ serverData: { views } }); + await openView({ + res_id: avatarUserId_1, + type: "ir.actions.act_window", + target: "current", + res_model: "m2x.avatar.user", + view_mode: "form", + views: [[false, "form"]], + }); + await contains(".o_field_many2one_avatar_user input", { value: "Mario" }); + triggerHotkey("control+k"); + await click(".o_command", { text: "Assign to ...ALT + I" }); + await contains(".o_command", { count: 5 }); + await contains(".o_command:eq(0)", { text: "Your Company, Mitchell Admin" }); + await contains(".o_command:eq(1)", { text: "Public user" }); + await contains(".o_command:eq(2)", { text: "Mario" }); + await contains(".o_command:eq(3)", { text: "Luigi" }); + await contains(".o_command:eq(4)", { text: "Yoshi" }); + await click("#o_command_3"); + await contains(".o_field_many2one_avatar_user input", { value: "Luigi" }); +}); - triggerHotkey("control+k"); - await nextTick(); - const idx = [...document.querySelectorAll(".o_command")] - .map((el) => el.textContent) - .indexOf("Assign to ...ALT + I"); - assert.ok(idx >= 0); +QUnit.test('many2one_avatar_user widget edited by the smart action "Assign to me"', async () => { + const pyEnv = await startServer(); + const userId_1 = pyEnv["res.users"].create({ name: "Mario" }); + const avatarUserId_1 = pyEnv["m2x.avatar.user"].create({ user_id: userId_1 }); + const views = { + "m2x.avatar.user,false,form": + '
', + }; + const { openView } = await start({ serverData: { views } }); + await openView({ + res_id: avatarUserId_1, + type: "ir.actions.act_window", + target: "current", + res_model: "m2x.avatar.user", + view_mode: "form", + views: [[false, "form"]], + }); + await contains(".o_field_many2one_avatar_user input", { value: "Mario" }); + triggerHotkey("control+k"); + await contains(".o_command", { text: "Assign/Unassign to meALT + SHIFT + I" }); + // Assign me + triggerHotkey("alt+shift+i"); + await contains(".o_field_many2one_avatar_user input", { + value: "Mitchell", // should be "Mitchell Admin" but session is not sync with currentUser + }); + // Unassign me + triggerHotkey("control+k"); + await click(".o_command", { text: "Assign/Unassign to meALT + SHIFT + I" }); + await contains(".o_field_many2one_avatar_user input", { value: "" }); +}); - await click([...document.querySelectorAll(".o_command")][idx]); - await nextTick(); - assert.deepEqual( - [...document.querySelectorAll(".o_command")].map((el) => el.textContent), - ["Your Company, Mitchell Admin", "Public user", "Mario", "Luigi", "Yoshi"] - ); - await click(document.body, "#o_command_3"); - await nextTick(); - await contains(".o_field_many2one_avatar_user input", { value: "Luigi" }); - } -); +QUnit.test('many2many_avatar_user widget edited by the smart action "Assign to..."', async () => { + const pyEnv = await startServer(); + const [userId_1, userId_2] = pyEnv["res.users"].create([ + { name: "Mario" }, + { name: "Yoshi" }, + { name: "Luigi" }, + ]); + const m2xAvatarUserId1 = pyEnv["m2x.avatar.user"].create({ + user_ids: [userId_1, userId_2], + }); + const views = { + "m2x.avatar.user,false,form": + '
', + }; + const { openView } = await start({ serverData: { views } }); + await openView({ + res_id: m2xAvatarUserId1, + type: "ir.actions.act_window", + target: "current", + res_model: "m2x.avatar.user", + view_mode: "form", + views: [[false, "form"]], + }); + await contains(".o_tag_badge_text", { count: 2 }); + await contains(".o_tag_badge_text:eq(0)", { text: "Mario" }); + await contains(".o_tag_badge_text:eq(1)", { text: "Yoshi" }); + triggerHotkey("control+k"); + await contains(".o_command", { text: "Assign to ...ALT + I" }); + triggerHotkey("alt+i"); + await contains(".o_command", { count: 3 }); + await contains(".o_command:eq(0)", { text: "Your Company, Mitchell Admin" }); + await contains(".o_command:eq(1)", { text: "Public user" }); + await contains(".o_command:eq(2)", { text: "Luigi" }); + await click("#o_command_2"); + await contains(".o_tag_badge_text", { count: 3 }); + await contains(".o_tag_badge_text:eq(0)", { text: "Mario" }); + await contains(".o_tag_badge_text:eq(1)", { text: "Yoshi" }); + await contains(".o_tag_badge_text:eq(2)", { text: "Luigi" }); +}); -QUnit.test( - 'many2one_avatar_user widget edited by the smart action "Assign to me"', - async (assert) => { - const pyEnv = await startServer(); - const [userId_1, userId_2] = pyEnv["res.users"].create([ - { name: "Mario" }, - { name: "Luigi" }, - ]); - const avatarUserId_1 = pyEnv["m2x.avatar.user"].create({ user_id: userId_1 }); - patchWithCleanup(session, { uid: userId_2, name: "Luigi" }); - const views = { - "m2x.avatar.user,false,form": - '
', - }; - const { openView } = await start({ serverData: { views } }); - await openView({ - res_id: avatarUserId_1, - type: "ir.actions.act_window", - target: "current", - res_model: "m2x.avatar.user", - view_mode: "form", - views: [[false, "form"]], - }); - await contains(".o_field_many2one_avatar_user input", { value: "Mario" }); - triggerHotkey("control+k"); - await nextTick(); - const idx = [...document.querySelectorAll(".o_command")] - .map((el) => el.textContent) - .indexOf("Assign/Unassign to meALT + SHIFT + I"); - assert.ok(idx >= 0); +QUnit.test('many2many_avatar_user widget edited by the smart action "Assign to me"', async () => { + const pyEnv = await startServer(); + const [userId_1, userId_2] = pyEnv["res.users"].create([{ name: "Mario" }, { name: "Yoshi" }]); + const m2xAvatarUserId1 = pyEnv["m2x.avatar.user"].create({ + user_ids: [userId_1, userId_2], + }); + const views = { + "m2x.avatar.user,false,form": + '
', + }; + const { openView } = await start({ serverData: { views } }); + await openView({ + res_id: m2xAvatarUserId1, + type: "ir.actions.act_window", + target: "current", + res_model: "m2x.avatar.user", + view_mode: "form", + views: [[false, "form"]], + }); + await contains(".o_tag_badge_text", { count: 2 }); + await contains(".o_tag_badge_text:eq(0)", { text: "Mario" }); + await contains(".o_tag_badge_text:eq(1)", { text: "Yoshi" }); + triggerHotkey("control+k"); + await contains(".o_command", { text: "Assign/Unassign to meALT + SHIFT + I" }); + // Assign me + triggerHotkey("alt+shift+i"); + await contains(".o_tag_badge_text", { count: 3 }); + await contains(".o_tag_badge_text:eq(0)", { text: "Mario" }); + await contains(".o_tag_badge_text:eq(1)", { text: "Yoshi" }); + await contains(".o_tag_badge_text:eq(2)", { text: "Your Company, Mitchell Admin" }); + // Unassign me + triggerHotkey("control+k"); + await contains(".o_command", { text: "Assign/Unassign to meALT + SHIFT + I" }); + triggerHotkey("alt+shift+i"); + await contains(".o_tag_badge_text", { count: 2 }); + await contains(".o_tag_badge_text:eq(0)", { text: "Mario" }); + await contains(".o_tag_badge_text:eq(1)", { text: "Yoshi" }); +}); - // Assign me (Luigi) - triggerHotkey("alt+shift+i"); - await nextTick(); - await contains(".o_field_many2one_avatar_user input", { value: "Luigi" }); +QUnit.test("avatar_user widget displays the appropriate user image in list view", async () => { + const pyEnv = await startServer(); + const userId = pyEnv["res.users"].create({ name: "Mario" }); + const avatarUserId = pyEnv["m2x.avatar.user"].create({ user_id: userId }); + const views = { + "m2x.avatar.user,false,list": + '', + }; + const { openView } = await start({ serverData: { views } }); + await openView({ + res_model: "m2x.avatar.user", + res_id: avatarUserId, + views: [[false, "list"]], + }); + await contains(`.o_m2o_avatar > img[data-src="/web/image/res.users/${userId}/avatar_128"]`); +}); - // Unassign me - triggerHotkey("control+k"); - await nextTick(); - await click([...document.querySelectorAll(".o_command")][idx]); - await nextTick(); - await contains(".o_field_many2one_avatar_user input", { value: "" }); - } -); - -QUnit.test( - 'many2many_avatar_user widget edited by the smart action "Assign to..."', - async (assert) => { - const pyEnv = await startServer(); - const [userId_1, userId_2] = pyEnv["res.users"].create([ - { name: "Mario" }, - { name: "Yoshi" }, - { name: "Luigi" }, - ]); - const m2xAvatarUserId1 = pyEnv["m2x.avatar.user"].create({ - user_ids: [userId_1, userId_2], - }); - const views = { - "m2x.avatar.user,false,form": - '
', - }; - const { openView } = await start({ serverData: { views } }); - await openView({ - res_id: m2xAvatarUserId1, - type: "ir.actions.act_window", - target: "current", - res_model: "m2x.avatar.user", - view_mode: "form", - views: [[false, "form"]], - }); - let userNames = [...document.querySelectorAll(".o_tag_badge_text")].map( - (el) => el.textContent - ); - assert.deepEqual(userNames, ["Mario", "Yoshi"]); - - triggerHotkey("control+k"); - await nextTick(); - const idx = [...document.querySelectorAll(".o_command")] - .map((el) => el.textContent) - .indexOf("Assign to ...ALT + I"); - assert.ok(idx >= 0); - - await click([...document.querySelectorAll(".o_command")][idx]); - await nextTick(); - assert.deepEqual( - [...document.querySelectorAll(".o_command")].map((el) => el.textContent), - ["Your Company, Mitchell Admin", "Public user", "Luigi"] - ); - - await click(document.body, "#o_command_2"); - await nextTick(); - userNames = [...document.querySelectorAll(".o_tag_badge_text")].map((el) => el.textContent); - assert.deepEqual(userNames, ["Mario", "Yoshi", "Luigi"]); - } -); - -QUnit.test( - 'many2many_avatar_user widget edited by the smart action "Assign to me"', - async (assert) => { - const pyEnv = await startServer(); - const [userId_1, userId_2] = pyEnv["res.users"].create([ - { name: "Mario" }, - { name: "Yoshi" }, - ]); - const m2xAvatarUserId1 = pyEnv["m2x.avatar.user"].create({ - user_ids: [userId_1, userId_2], - }); - const views = { - "m2x.avatar.user,false,form": - '
', - }; - const { openView } = await start({ serverData: { views } }); - await openView({ - res_id: m2xAvatarUserId1, - type: "ir.actions.act_window", - target: "current", - res_model: "m2x.avatar.user", - view_mode: "form", - views: [[false, "form"]], - }); - let userNames = [...document.querySelectorAll(".o_tag_badge_text")].map( - (el) => el.textContent - ); - assert.deepEqual(userNames, ["Mario", "Yoshi"]); - - triggerHotkey("control+k"); - await nextTick(); - const idx = [...document.querySelectorAll(".o_command")] - .map((el) => el.textContent) - .indexOf("Assign/Unassign to meALT + SHIFT + I"); - assert.ok(idx >= 0); - - // Assign me - triggerHotkey("alt+shift+i"); - await nextTick(); - userNames = [...document.querySelectorAll(".o_tag_badge_text")].map((el) => el.textContent); - assert.deepEqual(userNames, ["Mario", "Yoshi", "Your Company, Mitchell Admin"]); - - // Unassign me - triggerHotkey("control+k"); - await nextTick(); - await click([...document.querySelectorAll(".o_command")][idx]); - await nextTick(); - userNames = [...document.querySelectorAll(".o_tag_badge_text")].map((el) => el.textContent); - assert.deepEqual(userNames, ["Mario", "Yoshi"]); - } -); - -QUnit.test( - "avatar_user widget displays the appropriate user image in list view", - async (assert) => { - const pyEnv = await startServer(); - const userId = pyEnv["res.users"].create({ name: "Mario" }); - const avatarUserId = pyEnv["m2x.avatar.user"].create({ user_id: userId }); - const views = { - "m2x.avatar.user,false,list": - '', - }; - const { openView } = await start({ serverData: { views } }); - await openView({ - res_model: "m2x.avatar.user", - res_id: avatarUserId, - views: [[false, "list"]], - }); - assert.strictEqual( - $(".o_m2o_avatar > img")[0].getAttribute("data-src"), - `/web/image/res.users/${userId}/avatar_128` - ); - } -); - -QUnit.test( - "avatar_user widget displays the appropriate user image in kanban view", - async (assert) => { - const pyEnv = await startServer(); - const userId = pyEnv["res.users"].create({ name: "Mario" }); - const avatarUserId = pyEnv["m2x.avatar.user"].create({ user_id: userId }); - const views = { - "m2x.avatar.user,false,kanban": ` +QUnit.test("avatar_user widget displays the appropriate user image in kanban view", async () => { + const pyEnv = await startServer(); + const userId = pyEnv["res.users"].create({ name: "Mario" }); + const avatarUserId = pyEnv["m2x.avatar.user"].create({ user_id: userId }); + const views = { + "m2x.avatar.user,false,kanban": ` @@ -334,19 +266,15 @@ QUnit.test( `, - }; - const { openView } = await start({ serverData: { views } }); - await openView({ - res_model: "m2x.avatar.user", - res_id: avatarUserId, - views: [[false, "kanban"]], - }); - assert.strictEqual( - $(".o_m2o_avatar > img")[0].getAttribute("data-src"), - `/web/image/res.users/${userId}/avatar_128` - ); - } -); + }; + const { openView } = await start({ serverData: { views } }); + await openView({ + res_model: "m2x.avatar.user", + res_id: avatarUserId, + views: [[false, "kanban"]], + }); + await contains(`.o_m2o_avatar > img[data-src="/web/image/res.users/${userId}/avatar_128"]`); +}); QUnit.test("avatar card preview", async (assert) => { registry.category("services").add("multi_tab", fakeMultiTab, { force: true }); @@ -405,34 +333,28 @@ QUnit.test("avatar card preview", async (assert) => { await contains(".o_avatar_card", { count: 0 }); }); -QUnit.test( - "avatar_user widget displays the appropriate user image in form view", - async (assert) => { - const pyEnv = await startServer(); - const userId = pyEnv["res.users"].create({ name: "Mario" }); - const avatarUserId = pyEnv["m2x.avatar.user"].create({ user_ids: [userId] }); - const views = { - "m2x.avatar.user,false,form": - '
', - }; - const { openView } = await start({ - serverData: { views }, - }); - await openView({ - res_model: "m2x.avatar.user", - res_id: avatarUserId, - views: [[false, "form"]], - }); - assert.strictEqual( - document.body - .querySelector(".o_field_many2many_avatar_user.o_field_widget .o_avatar img") - .getAttribute("data-src"), - `/web/image/res.users/${userId}/avatar_128` - ); - } -); +QUnit.test("avatar_user widget displays the appropriate user image in form view", async () => { + const pyEnv = await startServer(); + const userId = pyEnv["res.users"].create({ name: "Mario" }); + const avatarUserId = pyEnv["m2x.avatar.user"].create({ user_ids: [userId] }); + const views = { + "m2x.avatar.user,false,form": + '
', + }; + const { openView } = await start({ + serverData: { views }, + }); + await openView({ + res_model: "m2x.avatar.user", + res_id: avatarUserId, + views: [[false, "form"]], + }); + await contains( + `.o_field_many2many_avatar_user.o_field_widget .o_avatar img[data-src="/web/image/res.users/${userId}/avatar_128"]` + ); +}); -QUnit.test("many2one_avatar_user widget in list view", async (assert) => { +QUnit.test("many2one_avatar_user widget in list view", async () => { const pyEnv = await startServer(); const partnerId = pyEnv["res.partner"].create({ name: "Partner 1" }); const userId = pyEnv["res.users"].create({ name: "Mario", partner_id: partnerId }); @@ -446,12 +368,11 @@ QUnit.test("many2one_avatar_user widget in list view", async (assert) => { res_model: "m2x.avatar.user", views: [[false, "list"]], }); - await click(document.body, ".o_data_cell .o_m2o_avatar > img"); - await contains(".o-mail-ChatWindow"); - assert.strictEqual($(".o-mail-ChatWindow-name").text(), "Partner 1"); + await click(".o_data_cell .o_m2o_avatar > img"); + await contains(".o-mail-ChatWindow-name", { text: "Partner 1" }); }); -QUnit.test("many2many_avatar_user widget in form view", async (assert) => { +QUnit.test("many2many_avatar_user widget in form view", async () => { const pyEnv = await startServer(); const partnerId = pyEnv["res.partner"].create({ name: "Partner 1" }); const userId = pyEnv["res.users"].create({ name: "Mario", partner_id: partnerId }); @@ -468,7 +389,6 @@ QUnit.test("many2many_avatar_user widget in form view", async (assert) => { res_id: avatarUserId, views: [[false, "form"]], }); - await click(document.body, ".o_field_many2many_avatar_user .o_avatar img"); - await contains(".o-mail-ChatWindow"); - assert.strictEqual($(".o-mail-ChatWindow-name").text(), "Partner 1"); + await click(".o_field_many2many_avatar_user .o_avatar img"); + await contains(".o-mail-ChatWindow-name", { text: "Partner 1" }); }); diff --git a/addons/mail/static/tests/web/follower_list_menu_tests.js b/addons/mail/static/tests/web/follower_list_menu_tests.js index be6dec9fd6b..6e827db877a 100644 --- a/addons/mail/static/tests/web/follower_list_menu_tests.js +++ b/addons/mail/static/tests/web/follower_list_menu_tests.js @@ -103,23 +103,18 @@ QUnit.test('click on "add followers" button', async (assert) => { options.onClose(); }, }); - await contains(".o-mail-Followers"); - await contains(".o-mail-Followers-button"); - assert.strictEqual($(".o-mail-Followers-counter").text(), "1"); - + await contains(".o-mail-Followers-counter", { text: "1" }); await click(".o-mail-Followers-button"); await contains(".o-mail-Followers-dropdown"); - await contains("a", { text: "Add Followers" }); - await click("a", { text: "Add Followers" }); await contains(".o-mail-Followers-dropdown", { count: 0 }); assert.verifySteps(["action:open_view"]); - assert.strictEqual($(".o-mail-Followers-counter").text(), "2"); - + await contains(".o-mail-Followers-counter", { text: "2" }); await click(".o-mail-Followers-button"); await contains(".o-mail-Follower", { count: 2 }); - assert.strictEqual($(".o-mail-Follower").text(), "François PerussePartner3"); + await contains(".o-mail-Follower:eq(0)", { text: "François Perusse" }); + await contains(".o-mail-Follower:eq(1)", { text: "Partner3" }); }); QUnit.test("click on remove follower", async (assert) => { diff --git a/addons/snailmail/static/tests/message/message_patch_tests.js b/addons/snailmail/static/tests/message/message_patch_tests.js index d25be805111..7cdbff0db69 100644 --- a/addons/snailmail/static/tests/message/message_patch_tests.js +++ b/addons/snailmail/static/tests/message/message_patch_tests.js @@ -6,7 +6,7 @@ import { makeDeferred, patchWithCleanup } from "@web/../tests/helpers/utils"; QUnit.module("message (patch)"); -QUnit.test("Sent", async (assert) => { +QUnit.test("Sent", async () => { const pyEnv = await startServer(); const partnerId = pyEnv["res.partner"].create({ name: "Someone", @@ -26,19 +26,12 @@ QUnit.test("Sent", async (assert) => { }); const { openFormView } = await start(); openFormView("res.partner", partnerId); - await contains(".o-mail-Message"); - await contains(".o-mail-Message-notification"); - await contains(".o-mail-Message-notification i"); - assert.hasClass($(".o-mail-Message-notification i"), "fa-paper-plane"); - - await click(".o-mail-Message-notification"); - await contains(".o-snailmail-SnailmailNotificationPopover"); - await contains(".o-snailmail-SnailmailNotificationPopover i"); - assert.hasClass($(".o-snailmail-SnailmailNotificationPopover i"), "fa-check"); - assert.strictEqual($(".o-snailmail-SnailmailNotificationPopover").text(), "Sent"); + await click(".o-mail-Message-notification i.fa-paper-plane"); + await contains(".o-snailmail-SnailmailNotificationPopover i.fa-check"); + await contains(".o-snailmail-SnailmailNotificationPopover", { text: "Sent" }); }); -QUnit.test("Canceled", async (assert) => { +QUnit.test("Canceled", async () => { const pyEnv = await startServer(); const partnerId = pyEnv["res.partner"].create({ name: "Someone", @@ -58,19 +51,12 @@ QUnit.test("Canceled", async (assert) => { }); const { openFormView } = await start(); openFormView("res.partner", partnerId); - await contains(".o-mail-Message"); - await contains(".o-mail-Message-notification"); - await contains(".o-mail-Message-notification i"); - assert.hasClass($(".o-mail-Message-notification i"), "fa-paper-plane"); - - await click(".o-mail-Message-notification"); - await contains(".o-snailmail-SnailmailNotificationPopover"); - await contains(".o-snailmail-SnailmailNotificationPopover i"); - assert.hasClass($(".o-snailmail-SnailmailNotificationPopover i"), "fa-trash-o"); - assert.strictEqual($(".o-snailmail-SnailmailNotificationPopover").text(), "Canceled"); + await click(".o-mail-Message-notification i.fa-paper-plane"); + await contains(".o-snailmail-SnailmailNotificationPopover i.fa-trash-o"); + await contains(".o-snailmail-SnailmailNotificationPopover", { text: "Canceled" }); }); -QUnit.test("Pending", async (assert) => { +QUnit.test("Pending", async () => { const pyEnv = await startServer(); const partnerId = pyEnv["res.partner"].create({ name: "Someone", @@ -90,16 +76,9 @@ QUnit.test("Pending", async (assert) => { }); const { openFormView } = await start(); openFormView("res.partner", partnerId); - await contains(".o-mail-Message"); - await contains(".o-mail-Message-notification"); - await contains(".o-mail-Message-notification i"); - assert.hasClass($(".o-mail-Message-notification i"), "fa-paper-plane"); - - await click(".o-mail-Message-notification"); - await contains(".o-snailmail-SnailmailNotificationPopover"); - await contains(".o-snailmail-SnailmailNotificationPopover i"); - assert.hasClass($(".o-snailmail-SnailmailNotificationPopover i"), "fa-clock-o"); - assert.strictEqual($(".o-snailmail-SnailmailNotificationPopover").text(), "Awaiting Dispatch"); + await click(".o-mail-Message-notification i.fa-paper-plane"); + await contains(".o-snailmail-SnailmailNotificationPopover i.fa-clock-o"); + await contains(".o-snailmail-SnailmailNotificationPopover", { text: "Awaiting Dispatch" }); }); QUnit.test("No Price Available", async (assert) => { @@ -133,18 +112,10 @@ QUnit.test("No Price Available", async (assert) => { }, }); openFormView("res.partner", partnerId); - await contains(".o-mail-Message"); - await contains(".o-mail-Message-notification"); - await contains(".o-mail-Message-notification i"); - assert.hasClass($(".o-mail-Message-notification i"), "fa-paper-plane"); - - await click(".o-mail-Message-notification"); - await contains(".o-snailmail-SnailmailError"); - assert.strictEqual( - $(".o-snailmail-SnailmailError .modal-body").text().trim(), - "The country to which you want to send the letter is not supported by our service." - ); - await contains("button", { text: "Cancel letter" }); + await click(".o-mail-Message-notification i.fa-paper-plane"); + await contains(".o-snailmail-SnailmailError .modal-body", { + text: "The country to which you want to send the letter is not supported by our service.", + }); await click("button", { text: "Cancel letter" }); await contains(".o-snailmail-SnailmailError", { count: 0 }); assert.verifySteps(["cancel_letter"]); @@ -181,18 +152,10 @@ QUnit.test("Credit Error", async (assert) => { }, }); openFormView("res.partner", partnerId); - await contains(".o-mail-Message"); - await contains(".o-mail-Message-notification"); - await contains(".o-mail-Message-notification i"); - assert.hasClass($(".o-mail-Message-notification i"), "fa-paper-plane"); - - await click(".o-mail-Message-notification"); - await contains(".o-snailmail-SnailmailError"); - assert.strictEqual( - $(".o-snailmail-SnailmailError p").text().trim(), - "The letter could not be sent due to insufficient credits on your IAP account." - ); - await contains("button", { text: "Re-send letter" }); + await click(".o-mail-Message-notification i.fa-paper-plane"); + await contains(".o-snailmail-SnailmailError p", { + text: "The letter could not be sent due to insufficient credits on your IAP account.", + }); await contains("button", { text: "Cancel letter" }); await click("button", { text: "Re-send letter" }); await contains(".o-snailmail-SnailmailError", { count: 0 }); @@ -230,18 +193,10 @@ QUnit.test("Trial Error", async (assert) => { }, }); openFormView("res.partner", partnerId); - await contains(".o-mail-Message"); - await contains(".o-mail-Message-notification"); - await contains(".o-mail-Message-notification i"); - assert.hasClass($(".o-mail-Message-notification i"), "fa-paper-plane"); - - await click(".o-mail-Message-notification"); - await contains(".o-snailmail-SnailmailError"); - assert.strictEqual( - $(".o-snailmail-SnailmailError p").text().trim(), - "You need credits on your IAP account to send a letter." - ); - await contains("button", { text: "Re-send letter" }); + await click(".o-mail-Message-notification i.fa-paper-plane"); + await contains(".o-snailmail-SnailmailError p", { + text: "You need credits on your IAP account to send a letter.", + }); await contains("button", { text: "Cancel letter" }); await click("button", { text: "Re-send letter" }); await contains(".o-snailmail-SnailmailError", { count: 0 }); @@ -278,12 +233,7 @@ QUnit.test("Format Error", async (assert) => { openFormatErrorActionDef.resolve(); }, }); - await contains(".o-mail-Message"); - await contains(".o-mail-Message-notification"); - await contains(".o-mail-Message-notification i"); - assert.hasClass($(".o-mail-Message-notification i"), "fa-paper-plane"); - - click(".o-mail-Message-notification").then(() => {}); + await click(".o-mail-Message-notification i.fa-paper-plane"); await openFormatErrorActionDef; assert.verifySteps(["do_action"]); }); @@ -317,12 +267,7 @@ QUnit.test("Missing Required Fields", async (assert) => { openRequiredFieldsActionDef.resolve(); }, }); - await contains(".o-mail-Message"); - await contains(".o-mail-Message-notification"); - await contains(".o-mail-Message-notification i"); - assert.hasClass($(".o-mail-Message-notification i"), "fa-paper-plane"); - - click(".o-mail-Message-notification").then(() => {}); + await click(".o-mail-Message-notification i.fa-paper-plane"); await openRequiredFieldsActionDef; assert.verifySteps(["do_action"]); }); diff --git a/addons/snailmail/static/tests/messaging_menu/messaging_menu_patch_tests.js b/addons/snailmail/static/tests/messaging_menu/messaging_menu_patch_tests.js index 652a7938502..ea63e17fba0 100644 --- a/addons/snailmail/static/tests/messaging_menu/messaging_menu_patch_tests.js +++ b/addons/snailmail/static/tests/messaging_menu/messaging_menu_patch_tests.js @@ -25,15 +25,14 @@ QUnit.test("mark as read", async () => { await click(".o_menu_systray i[aria-label='Messages']"); await contains(".o-mail-NotificationItem"); await triggerEvent($(".o-mail-NotificationItem")[0], null, "mouseenter"); - await contains(".o-mail-NotificationItem [title='Mark As Read']"); - await contains( - ".o-mail-NotificationItem:contains(An error occurred when sending a letter with Snailmail.)" - ); + await contains(".o-mail-NotificationItem-text", { + text: "An error occurred when sending a letter with Snailmail.", + }); await click(".o-mail-NotificationItem [title='Mark As Read']"); await contains(".o-mail-NotificationItem", { count: 0 }); }); -QUnit.test("notifications grouped by notification_type", async (assert) => { +QUnit.test("notifications grouped by notification_type", async () => { const pyEnv = await startServer(); const partnerId = await pyEnv["res.partner"].create({}); const [messageId_1, messageId_2] = pyEnv["mail.message"].create([ @@ -75,20 +74,16 @@ QUnit.test("notifications grouped by notification_type", async (assert) => { await start(); await click(".o_menu_systray i[aria-label='Messages']"); await contains(".o-mail-NotificationItem", { count: 2 }); - assert.ok($(".o-mail-NotificationItem:eq(0)").text().includes("Partner")); - assert.ok($(".o-mail-NotificationItem:eq(0)").text().includes("2")); // counter - assert.ok( - $(".o-mail-NotificationItem:eq(0)") - .text() - .includes("An error occurred when sending an email") - ); - assert.ok($(".o-mail-NotificationItem:eq(1)").text().includes("Partner")); - assert.ok($(".o-mail-NotificationItem:eq(1)").text().includes("2")); // counter - assert.ok( - $(".o-mail-NotificationItem:eq(1)") - .text() - .includes("An error occurred when sending a letter with Snailmail.") - ); + await contains(".o-mail-NotificationItem-name:eq(0)", { text: "Partner" }); + await contains(".o-mail-NotificationItem-counter:eq(0)", { text: "2" }); + await contains(".o-mail-NotificationItem-text:eq(0)", { + text: "An error occurred when sending an email", + }); + await contains(".o-mail-NotificationItem-name:eq(1)", { text: "Partner" }); + await contains(".o-mail-NotificationItem-counter:eq(1)", { text: "2" }); + await contains(".o-mail-NotificationItem-text:eq(1)", { + text: "An error occurred when sending a letter with Snailmail.", + }); }); QUnit.test("grouped notifications by document model", async (assert) => { @@ -144,7 +139,6 @@ QUnit.test("grouped notifications by document model", async (assert) => { }, }); await click(".o_menu_systray i[aria-label='Messages']"); - await contains(".o-mail-NotificationItem"); await contains(".o-mail-NotificationItem-name", { text: "Partner" }); await contains(".o-mail-NotificationItem-counter", { text: "2" }); await click(".o-mail-NotificationItem"); diff --git a/addons/test_mail/static/tests/activity_tests.js b/addons/test_mail/static/tests/activity_tests.js index 2c803528a0f..9f2ce01e18b 100644 --- a/addons/test_mail/static/tests/activity_tests.js +++ b/addons/test_mail/static/tests/activity_tests.js @@ -2,7 +2,7 @@ import { ActivityModel } from "@mail/views/web/activity/activity_model"; import { ActivityRenderer } from "@mail/views/web/activity/activity_renderer"; -import { start, startServer } from "@mail/../tests/helpers/test_utils"; +import { contains, start, startServer } from "@mail/../tests/helpers/test_utils"; import { serializeDate } from "@web/core/l10n/dates"; import testUtils from "@web/../tests/legacy/helpers/test_utils"; @@ -94,10 +94,6 @@ QUnit.module("test_mail", {}, function () { }, }); - var activityDateFormat = function (date) { - return DateTime.now().toLocaleString({ day: "numeric", month: "short" }); - }; - QUnit.test("activity view: simple activity rendering", async function (assert) { assert.expect(14); const mailTestActivityIds = pyEnv["mail.test.activity"].search([]); @@ -137,7 +133,7 @@ QUnit.module("test_mail", {}, function () { const $activity = $(document.querySelector(".o_activity_view")); assert.containsOnce($activity, "table", "should have a table"); - var $th1 = $activity.find("table thead tr:first th:nth-child(2)"); + const $th1 = $activity.find("table thead tr:first th:nth-child(2)"); assert.containsOnce( $th1, "span:first:contains(Email)", @@ -160,7 +156,7 @@ QUnit.module("test_mail", {}, function () { "1 Today", "the counter progressbars should be correctly displayed" ); - var $th2 = $activity.find("table thead tr:first th:nth-child(3)"); + const $th2 = $activity.find("table thead tr:first th:nth-child(3)"); assert.containsOnce( $th2, "span:first:contains(Call)", @@ -187,7 +183,7 @@ QUnit.module("test_mail", {}, function () { 'should contain "Meeting Room Furnitures" in first colum of second row' ); - var today = activityDateFormat(new Date()); + const today = DateTime.now().toLocaleString({ day: "numeric", month: "short" }); assert.ok( $activity.find( @@ -197,7 +193,7 @@ QUnit.module("test_mail", {}, function () { ).length, "should contain an activity for today in second cell of first line " + today ); - var td = "table tbody tr:nth-child(1) td.o_activity_empty_cell"; + const td = "table tbody tr:nth-child(1) td.o_activity_empty_cell"; assert.containsN( $activity, td, @@ -261,26 +257,18 @@ QUnit.module("test_mail", {}, function () { } ); - QUnit.test("activity view: no content rendering", async function (assert) { - assert.expect(2); - - const { openView, pyEnv } = await start({ - serverData, - }); + QUnit.test("activity view: no content rendering", async function () { + const { openView, pyEnv } = await start({ serverData }); // reset incompatible setup pyEnv["mail.activity.type"].unlink(pyEnv["mail.activity.type"].search([])); await openView({ res_model: "mail.test.activity", views: [[false, "activity"]], }); - const $activity = $(document); - - assert.containsOnce($activity, ".o_view_nocontent", "should display the no content helper"); - assert.strictEqual( - $activity.find(".o_view_nocontent .o_view_nocontent_empty_folder").text().trim(), - "No data to display", - "should display the no content helper text" - ); + await contains(".o_view_nocontent"); + await contains(".o_view_nocontent .o_view_nocontent_empty_folder", { + text: "No data to display", + }); }); QUnit.test("activity view: batch send mail on activity", async function (assert) { @@ -600,7 +588,7 @@ QUnit.module("test_mail", {}, function () { patchWithCleanup(env.services.action, { doAction(action, options) { assert.step("doAction"); - var expectedAction = { + const expectedAction = { context: { default_res_id: mailTestActivityId1, default_res_model: "mail.test.activity", @@ -631,7 +619,7 @@ QUnit.module("test_mail", {}, function () { ); await testUtils.dom.click(activity.find("table tfoot tr .o_record_selector")); // search create dialog - var $modal = $(".modal-lg"); + const $modal = $(".modal-lg"); assert.strictEqual( $modal.find(".o_data_row").length, 3, @@ -677,7 +665,7 @@ QUnit.module("test_mail", {}, function () { await testUtils.dom.click( document.querySelector(".o_activity_view .o_data_row .o_activity_empty_cell") ); - assert.containsOnce($, ".modal.o_technical_modal", "Activity Modal should be opened"); + await contains(".modal.o_technical_modal", "Activity Modal should be opened"); await testUtils.dom.click($('.modal.o_technical_modal button[special="cancel"]')); await contains(".modal.o_technical_modal", { count: 0 }); diff --git a/addons/website_livechat/static/tests/messaging_service_patch_tests.js b/addons/website_livechat/static/tests/messaging_service_patch_tests.js index f42cc85f92a..fd08c1e6c77 100644 --- a/addons/website_livechat/static/tests/messaging_service_patch_tests.js +++ b/addons/website_livechat/static/tests/messaging_service_patch_tests.js @@ -1,10 +1,10 @@ -/** @odoo-module */ +/* @odoo-module */ -import { startServer, start, afterNextRender } from "@mail/../tests/helpers/test_utils"; +import { contains, startServer, start } from "@mail/../tests/helpers/test_utils"; QUnit.module("messaging service (patch)"); -QUnit.test("Should open chat window on send chat request to website visitor", async (assert) => { +QUnit.test("Should open chat window on send chat request to website visitor", async () => { const pyEnv = await startServer(); const visitorId = pyEnv["website.visitor"].create({ display_name: "Visitor #11", @@ -26,15 +26,12 @@ QUnit.test("Should open chat window on send chat request to website visitor", as waitUntilDataLoaded: false, waitUntilMessagesLoaded: false, }); - await afterNextRender(async () => { - await env.services.rpc("/web/dataset/call_button", { - args: [visitorId], - kwargs: { context: env.context }, - method: "action_send_chat_request", - model: "website.visitor", - }); + await env.services.rpc("/web/dataset/call_button", { + args: [visitorId], + kwargs: { context: env.context }, + method: "action_send_chat_request", + model: "website.visitor", }); - assert.containsOnce($, ".o-mail-ChatWindow"); - assert.ok(document.activeElement, $(".o-mail-ChatWindow .o-mail-Composer-input")[0]); - assert.strictEqual($(".o-mail-ChatWindow-name").text(), "Visitor #11"); + await contains(".o-mail-ChatWindow-name", { text: "Visitor #11" }); + await contains(".o-mail-ChatWindow .o-mail-Composer-input:focus"); });