[REF] mail, *: clean click and contains API
* = test_mail, hr, im_livechat - Allow only selectors - Add `value` check to `contains` - Remove return from `click` closes odoo/odoo#132799 Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
@@ -159,11 +159,7 @@ QUnit.test(
|
||||
res_id: avatarId,
|
||||
views: [[false, "form"]],
|
||||
});
|
||||
assert.strictEqual(
|
||||
document.querySelector(".o_field_widget[name=employee_id] input").value.trim(),
|
||||
"Mario"
|
||||
);
|
||||
|
||||
await contains(".o_field_widget[name=employee_id] input", 1, { value: "Mario" });
|
||||
await dom.click(document.querySelector(".o_m2o_avatar > img"));
|
||||
await contains(
|
||||
".o_notification.border-info:contains(You can only chat with employees that have a dedicated user.)"
|
||||
|
||||
@@ -139,15 +139,10 @@ QUnit.test("use a canned response", async (assert) => {
|
||||
await openDiscuss(channelId);
|
||||
await contains(".o-mail-Composer-suggestionList");
|
||||
await contains(".o-mail-Composer-suggestionList .o-open", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "" });
|
||||
await insertText(".o-mail-Composer-input", ":");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
assert.strictEqual(
|
||||
$(".o-mail-Composer-input").val().replace(/\s/, " "),
|
||||
"Hello! How are you? ",
|
||||
"canned response + additional whitespace afterwards"
|
||||
);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "Hello! How are you? " });
|
||||
});
|
||||
|
||||
QUnit.test("use a canned response some text", async (assert) => {
|
||||
@@ -168,21 +163,15 @@ QUnit.test("use a canned response some text", async (assert) => {
|
||||
const { openDiscuss } = await start();
|
||||
await openDiscuss(channelId);
|
||||
await contains(".o-mail-Composer-suggestionList");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await insertText(".o-mail-Composer-input", "bluhbluh ");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "bluhbluh ");
|
||||
await insertText(".o-mail-Composer-input", ":");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
assert.strictEqual(
|
||||
$(".o-mail-Composer-input").val().replace(/\s/, " "),
|
||||
"bluhbluh Hello! How are you? ",
|
||||
"previous content + canned response substitution + additional whitespace afterwards"
|
||||
);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "bluhbluh Hello! How are you? " });
|
||||
});
|
||||
|
||||
QUnit.test("add an emoji after a canned response", async (assert) => {
|
||||
QUnit.test("add an emoji after a canned response", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({
|
||||
anonymous_name: "Visitor 20",
|
||||
@@ -200,21 +189,11 @@ QUnit.test("add an emoji after a canned response", async (assert) => {
|
||||
const { openDiscuss } = await start();
|
||||
await openDiscuss(channelId);
|
||||
await contains(".o-mail-Composer-suggestionList");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "" });
|
||||
await insertText(".o-mail-Composer-input", ":");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
assert.strictEqual(
|
||||
$(".o-mail-Composer-input").val().replace(/\s/, " "),
|
||||
"Hello! How are you? ",
|
||||
"previous content + canned response substitution + additional whitespace afterwards"
|
||||
);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "Hello! How are you? " });
|
||||
await click("button[aria-label='Emojis']");
|
||||
await click(".o-Emoji:contains(😊)");
|
||||
await contains(".o-Emoji", 0);
|
||||
assert.strictEqual(
|
||||
$(".o-mail-Composer-input").val().replace(/\s/, " "),
|
||||
"Hello! How are you? 😊"
|
||||
);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "Hello! How are you? 😊" });
|
||||
});
|
||||
|
||||
@@ -25,7 +25,6 @@ QUnit.test("Suggestions are shown after delimiter was used in text (:)", async (
|
||||
await contains(".o-mail-Composer-suggestion");
|
||||
await insertText(".o-mail-Composer-input", ")");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await insertText(".o-mail-Composer-input", " ");
|
||||
await insertText(".o-mail-Composer-input", ":");
|
||||
await insertText(".o-mail-Composer-input", " :");
|
||||
await contains(".o-mail-Composer-suggestion:contains(hello)");
|
||||
});
|
||||
|
||||
@@ -875,7 +875,7 @@ QUnit.test("chat window: composer state conservation on toggle discuss", async (
|
||||
views: [[false, "form"]],
|
||||
});
|
||||
await contains(".o-mail-Composer-footer .o-mail-AttachmentList .o-mail-AttachmentCard", 2);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "XDU for the win !");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "XDU for the win !" });
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
@@ -1132,9 +1132,9 @@ QUnit.test(
|
||||
await click(".o_menu_systray i[aria-label='Messages']");
|
||||
await click(".o-mail-NotificationItem");
|
||||
await contains(".o-mail-ChatWindow .o-mail-Composer-input:focus");
|
||||
const expand = await click(".o-mail-Message [title='Expand']");
|
||||
await click(".o-mail-Message [title='Expand']");
|
||||
await contains(".o-mail-Message-moreMenu.dropdown-menu");
|
||||
expand.focus(); // necessary otherwise focus is in composer input
|
||||
document.querySelector(".o-mail-Message [title='Expand']").focus(); // necessary otherwise focus is in composer input
|
||||
|
||||
triggerHotkey("ArrowDown");
|
||||
await contains(".o-mail-Message-moreMenu .dropdown-item:eq(0).focus");
|
||||
@@ -1158,9 +1158,9 @@ QUnit.test(
|
||||
await start();
|
||||
await click(".o_menu_systray i[aria-label='Messages']");
|
||||
await click(".o-mail-NotificationItem");
|
||||
const expand = await click(".o-mail-Message [title='Expand']");
|
||||
await click(".o-mail-Message [title='Expand']");
|
||||
await contains(".o-mail-Message-moreMenu.dropdown-menu");
|
||||
expand.focus(); // necessary otherwise focus is in composer input
|
||||
document.querySelector(".o-mail-Message [title='Expand']").focus(); // necessary otherwise focus is in composer input
|
||||
triggerHotkey("Escape");
|
||||
await contains(".o-mail-Message-moreMenu.dropdown-menu", 0);
|
||||
await contains(".o-mail-ChatWindow");
|
||||
|
||||
@@ -69,7 +69,7 @@ QUnit.test(
|
||||
|
||||
QUnit.test(
|
||||
"composer text input placeholder should contain channel name when thread does not have specific correspondent",
|
||||
async (assert) => {
|
||||
async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({
|
||||
channel_type: "channel",
|
||||
@@ -81,15 +81,14 @@ QUnit.test(
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test("add an emoji", async (assert) => {
|
||||
QUnit.test("add an emoji", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "swamp-safari" });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
await click("button[aria-label='Emojis']");
|
||||
await click(".o-Emoji:contains(😤)");
|
||||
await contains(".o-Emoji", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "😤");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "😤" });
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
@@ -106,34 +105,31 @@ QUnit.test(
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test("add an emoji after some text", async (assert) => {
|
||||
QUnit.test("add an emoji after some text", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "beyblade-room" });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "Blabla");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "Blabla");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "Blabla" });
|
||||
|
||||
await click("button[aria-label='Emojis']");
|
||||
await click(".o-Emoji:contains(🤑)");
|
||||
await contains(".o-Emoji", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "Blabla🤑");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "Blabla🤑" });
|
||||
});
|
||||
|
||||
QUnit.test("add emoji replaces (keyboard) text selection [REQUIRE FOCUS]", async (assert) => {
|
||||
QUnit.test("add emoji replaces (keyboard) text selection [REQUIRE FOCUS]", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "pétanque-tournament-14" });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
const textarea = (await insertText(".o-mail-Composer-input", "Blabla"))[0];
|
||||
assert.strictEqual(textarea.value, "Blabla");
|
||||
|
||||
await insertText(".o-mail-Composer-input", "Blabla");
|
||||
const textarea = (await contains(".o-mail-Composer-input", 1, { value: "Blabla" }))[0];
|
||||
// simulate selection of all the content by keyboard
|
||||
textarea.setSelectionRange(0, textarea.value.length);
|
||||
await click("button[aria-label='Emojis']");
|
||||
await click(".o-Emoji:contains(🤠)");
|
||||
await contains(".o-Emoji", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "🤠");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "🤠" });
|
||||
});
|
||||
|
||||
QUnit.test("Cursor is positioned after emoji after adding it", async (assert) => {
|
||||
@@ -150,21 +146,19 @@ QUnit.test("Cursor is positioned after emoji after adding it", async (assert) =>
|
||||
assert.strictEqual(textarea.selectionEnd, expectedPos);
|
||||
});
|
||||
|
||||
QUnit.test("selected text is not replaced after cancelling the selection", async (assert) => {
|
||||
QUnit.test("selected text is not replaced after cancelling the selection", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "pétanque-tournament-14" });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
const textarea = (await insertText(".o-mail-Composer-input", "Blabla"))[0];
|
||||
assert.strictEqual(textarea.value, "Blabla");
|
||||
|
||||
await insertText(".o-mail-Composer-input", "Blabla");
|
||||
const textarea = (await contains(".o-mail-Composer-input", 1, { value: "Blabla" }))[0];
|
||||
// simulate selection of all the content by keyboard
|
||||
textarea.setSelectionRange(0, textarea.value.length);
|
||||
await click(".o-mail-Discuss-content");
|
||||
await click("button[aria-label='Emojis']");
|
||||
await click(".o-Emoji:contains(🤠)");
|
||||
await contains(".o-Emoji", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "Blabla🤠");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "Blabla🤠" });
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
@@ -182,8 +176,8 @@ QUnit.test(
|
||||
const textarea = $(".o-mail-Composer-input")[0];
|
||||
textarea.setSelectionRange(0, textarea.value.length);
|
||||
await nextTick();
|
||||
await click($(".o-mail-DiscussSidebarChannel:eq(1)"));
|
||||
await click($(".o-mail-DiscussSidebarChannel:eq(0)"));
|
||||
await click(".o-mail-DiscussSidebarChannel:eq(1)");
|
||||
await click(".o-mail-DiscussSidebarChannel:eq(0)");
|
||||
assert.ok(textarea.selectionStart === 0 && textarea.selectionEnd === textarea.value.length);
|
||||
}
|
||||
);
|
||||
@@ -260,17 +254,17 @@ QUnit.test(
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test("composer text input cleared on message post", async (assert) => {
|
||||
QUnit.test("composer text input cleared on message post", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "au-secours-aidez-moi" });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
const textarea = await insertText(".o-mail-Composer-input", "test message");
|
||||
assert.strictEqual(textarea.val(), "test message");
|
||||
await insertText(".o-mail-Composer-input", "test message");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "test message" });
|
||||
|
||||
await click(".o-mail-Composer-send:not([disabled])");
|
||||
await contains(".o-mail-Message");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "" });
|
||||
});
|
||||
|
||||
QUnit.test("send message only once when button send is clicked twice quickly", async () => {
|
||||
@@ -284,12 +278,12 @@ QUnit.test("send message only once when button send is clicked twice quickly", a
|
||||
await contains(".o-mail-Message");
|
||||
});
|
||||
|
||||
QUnit.test('send button on discuss.channel should have "Send" as label', async (assert) => {
|
||||
QUnit.test('send button on discuss.channel should have "Send" as label', async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "minecraft-wii-u" });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
assert.strictEqual((await contains(".o-mail-Composer-send:disabled")).text().trim(), "Send");
|
||||
await contains(".o-mail-Composer-send:disabled:contains(Send)");
|
||||
});
|
||||
|
||||
QUnit.test("Show send button in mobile", async () => {
|
||||
@@ -306,7 +300,7 @@ QUnit.test("Show send button in mobile", async () => {
|
||||
|
||||
QUnit.test(
|
||||
"composer textarea content is retained when changing channel then going back",
|
||||
async (assert) => {
|
||||
async () => {
|
||||
const pyEnv = await startServer();
|
||||
const [channelId] = pyEnv["discuss.channel"].create([
|
||||
{ name: "minigolf-galaxy-iv" },
|
||||
@@ -315,21 +309,19 @@ QUnit.test(
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "According to all known laws of aviation,");
|
||||
await click($("span:contains('epic-shrek-lovers')"));
|
||||
await click("span:contains('epic-shrek-lovers')");
|
||||
await contains("textarea.o-mail-Composer-input[placeholder='Message #epic-shrek-lovers…']");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await click($("span:contains('minigolf-galaxy-iv')"));
|
||||
await contains(".o-mail-Composer-input", 1, { value: "" });
|
||||
await click("span:contains('minigolf-galaxy-iv')");
|
||||
await contains(
|
||||
"textarea.o-mail-Composer-input[placeholder='Message #minigolf-galaxy-iv…']"
|
||||
);
|
||||
assert.strictEqual(
|
||||
$(".o-mail-Composer-input").val(),
|
||||
"According to all known laws of aviation,"
|
||||
"textarea.o-mail-Composer-input[placeholder='Message #minigolf-galaxy-iv…']",
|
||||
1,
|
||||
{ value: "According to all known laws of aviation," }
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test("add an emoji after a partner mention", async (assert) => {
|
||||
QUnit.test("add an emoji after a partner mention", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const partnerId = pyEnv["res.partner"].create({
|
||||
email: "testpartner@odoo.com",
|
||||
@@ -344,18 +336,16 @@ QUnit.test("add an emoji after a partner mention", async (assert) => {
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
assert.strictEqual((await contains(".o-mail-Composer-input")).val(), "");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "" });
|
||||
await insertText(".o-mail-Composer-input", "@Te");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val().replace(/\s/, " "), "@TestPartner ");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "@TestPartner " });
|
||||
await click("button[aria-label='Emojis']");
|
||||
await click(".o-Emoji:contains(😊)");
|
||||
await contains(".o-Emoji", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val().replace(/\s/, " "), "@TestPartner 😊");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "@TestPartner 😊" });
|
||||
});
|
||||
|
||||
QUnit.test("mention a channel after some text", async (assert) => {
|
||||
QUnit.test("mention a channel after some text", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({
|
||||
name: "General",
|
||||
@@ -363,25 +353,15 @@ QUnit.test("mention a channel after some text", async (assert) => {
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
assert.strictEqual((await contains(".o-mail-Composer-input")).val(), "");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "" });
|
||||
await insertText(".o-mail-Composer-input", "bluhbluh ");
|
||||
assert.strictEqual(
|
||||
$(".o-mail-Composer-input").val(),
|
||||
"bluhbluh ",
|
||||
"text content of composer should have content"
|
||||
);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "bluhbluh " });
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
assert.strictEqual(
|
||||
$(".o-mail-Composer-input").val().replace(/\s/, " "),
|
||||
"bluhbluh #General ",
|
||||
"previous content + mentioned channel + additional whitespace afterwards"
|
||||
);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "bluhbluh #General " });
|
||||
});
|
||||
|
||||
QUnit.test("add an emoji after a channel mention", async (assert) => {
|
||||
QUnit.test("add an emoji after a channel mention", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({
|
||||
name: "General",
|
||||
@@ -389,33 +369,23 @@ QUnit.test("add an emoji after a channel mention", async (assert) => {
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
assert.strictEqual((await contains(".o-mail-Composer-input")).val(), "");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "" });
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
assert.strictEqual(
|
||||
$(".o-mail-Composer-input").val().replace(/\s/, " "),
|
||||
"#General ",
|
||||
"previous content + mentioned channel + additional whitespace afterwards"
|
||||
);
|
||||
|
||||
// select emoji
|
||||
await contains(".o-mail-Composer-input", 1, { value: "#General " });
|
||||
await click("button[aria-label='Emojis']");
|
||||
await click(".o-Emoji:contains(😊)");
|
||||
await contains(".o-Emoji", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val().replace(/\s/, " "), "#General 😊");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "#General 😊" });
|
||||
});
|
||||
|
||||
QUnit.test("pending mentions are kept when toggling composer", async (assert) => {
|
||||
QUnit.test("pending mentions are kept when toggling composer", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const { openFormView } = await start();
|
||||
openFormView("res.partner", pyEnv.currentPartnerId);
|
||||
await click("button:contains(Send message)");
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await click(".o-mail-Composer-suggestion:contains(Mitchell Admin)");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "@Mitchell Admin ");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "@Mitchell Admin " });
|
||||
await click("button:contains(Send message)");
|
||||
await contains(".o-mail-Composer-input", 0);
|
||||
await click("button:contains(Send message)");
|
||||
@@ -455,7 +425,7 @@ QUnit.test("leave command on channel", async () => {
|
||||
await insertText(".o-mail-Composer-input", "/leave");
|
||||
await contains(".o-mail-Composer-suggestion", 1);
|
||||
triggerHotkey("Enter");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "/leave " });
|
||||
triggerHotkey("Enter");
|
||||
await contains(".o-mail-DiscussSidebarChannel:contains(general)", 0);
|
||||
await contains(".o-mail-Discuss:contains(No conversation selected.)");
|
||||
@@ -499,7 +469,7 @@ QUnit.test("leave command on chat", async () => {
|
||||
await insertText(".o-mail-Composer-input", "/leave");
|
||||
await contains(".o-mail-Composer-suggestion", 1);
|
||||
triggerHotkey("Enter");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "/leave " });
|
||||
triggerHotkey("Enter");
|
||||
await contains(".o-mail-DiscussSidebarChannel:contains(Chuck Norris)", 0);
|
||||
await contains(".o-mail-Discuss:contains(No conversation selected.)");
|
||||
@@ -514,7 +484,7 @@ QUnit.test("Can post suggestions", async () => {
|
||||
await insertText(".o-mail-Composer-input", "#general");
|
||||
await contains(".o-mail-Composer-suggestion", 1);
|
||||
triggerHotkey("Enter");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "#general " });
|
||||
triggerHotkey("Enter");
|
||||
await contains(".o-mail-Message .o_channel_redirect");
|
||||
});
|
||||
@@ -537,7 +507,7 @@ QUnit.test(
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test("quick edit last self-message from UP arrow", async (assert) => {
|
||||
QUnit.test("quick edit last self-message from UP arrow", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "general" });
|
||||
pyEnv["mail.message"].create({
|
||||
@@ -558,7 +528,7 @@ QUnit.test("quick edit last self-message from UP arrow", async (assert) => {
|
||||
|
||||
triggerHotkey("Escape");
|
||||
await contains(".o-mail-Message .o-mail-Composer", 0);
|
||||
assert.strictEqual(document.activeElement, $(".o-mail-Composer-input")[0]);
|
||||
await contains(".o-mail-Composer-input:focus");
|
||||
|
||||
// non-empty composer should not trigger quick edit
|
||||
await insertText(".o-mail-Composer-input", "Shrek");
|
||||
@@ -570,7 +540,7 @@ QUnit.test("quick edit last self-message from UP arrow", async (assert) => {
|
||||
await contains(".o-mail-Message .o-mail-Composer", 0);
|
||||
});
|
||||
|
||||
QUnit.test("Select composer suggestion via Enter does not send the message", async (assert) => {
|
||||
QUnit.test("Select composer suggestion via Enter does not send the message", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const partnerId = pyEnv["res.partner"].create({
|
||||
email: "shrek@odoo.com",
|
||||
@@ -589,9 +559,9 @@ QUnit.test("Select composer suggestion via Enter does not send the message", asy
|
||||
await insertText(".o-mail-Composer-input", "@Shrek");
|
||||
await contains(".o-mail-Composer-suggestion");
|
||||
triggerHotkey("Enter");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "@Shrek " });
|
||||
// weak test, no guarantee that we waited long enough for the potential message to be posted
|
||||
await contains(".o-mail-Message", 0);
|
||||
assert.equal($(".o-mail-Composer-input").val().trim(), "@Shrek");
|
||||
});
|
||||
|
||||
QUnit.test("composer: drop attachments", async () => {
|
||||
@@ -833,7 +803,7 @@ QUnit.test("Show recipient list when there is more than 5 followers.", async ()
|
||||
|
||||
QUnit.test(
|
||||
"Uploading multiple files in the composer create multiple temporary attachments",
|
||||
async (assert) => {
|
||||
async () => {
|
||||
const pyEnv = await startServer();
|
||||
// Promise to block attachment uploading
|
||||
const uploadPromise = makeDeferred();
|
||||
|
||||
@@ -52,7 +52,7 @@ QUnit.test(
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test("add an emoji after a command", async (assert) => {
|
||||
QUnit.test("add an emoji after a command", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({
|
||||
name: "General",
|
||||
@@ -60,18 +60,11 @@ QUnit.test("add an emoji after a command", async (assert) => {
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
assert.strictEqual((await contains(".o-mail-Composer-input")).val(), "");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "" });
|
||||
await insertText(".o-mail-Composer-input", "/");
|
||||
await click(".o-mail-Composer-suggestion:eq(0)");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
assert.strictEqual(
|
||||
$(".o-mail-Composer-input").val().replace(/\s/, " "),
|
||||
"/who ",
|
||||
"previous content + used command + additional whitespace afterwards"
|
||||
);
|
||||
|
||||
await contains(".o-mail-Composer-input", 1, { value: "/who " });
|
||||
await click("button[aria-label='Emojis']");
|
||||
await click(".o-Emoji:contains(😊)");
|
||||
await contains(".o-Emoji", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val().replace(/\s/, " "), "/who 😊");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "/who 😊" });
|
||||
});
|
||||
|
||||
@@ -31,43 +31,36 @@ QUnit.test('display command suggestions on typing "/"', async () => {
|
||||
await contains(".o-mail-Composer-suggestionList .o-open");
|
||||
});
|
||||
|
||||
QUnit.test("use a command for a specific channel type", async (assert) => {
|
||||
QUnit.test("use a command for a specific channel type", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ channel_type: "chat" });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
await contains(".o-mail-Composer-suggestionList");
|
||||
await contains(".o-mail-Composer-suggestionList .o-open", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "" });
|
||||
await insertText(".o-mail-Composer-input", "/");
|
||||
await click(".o-mail-Composer-suggestion:eq(0)");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
assert.strictEqual(
|
||||
$(".o-mail-Composer-input").val().replace(/\s/, " "),
|
||||
"/who ",
|
||||
"command + additional whitespace afterwards"
|
||||
);
|
||||
await click(".o-mail-Composer-suggestion:contains(who)");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "/who " });
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"command suggestion should only open if command is the first character",
|
||||
async (assert) => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({
|
||||
name: "General",
|
||||
channel_type: "channel",
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
await contains(".o-mail-Composer-suggestionList");
|
||||
await contains(".o-mail-Composer-suggestionList .o-open", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await insertText(".o-mail-Composer-input", "bluhbluh ");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "bluhbluh ");
|
||||
await insertText(".o-mail-Composer-input", "/");
|
||||
await contains(".o-mail-Composer-suggestionList .o-open", 0);
|
||||
}
|
||||
);
|
||||
QUnit.test("command suggestion should only open if command is the first character", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({
|
||||
name: "General",
|
||||
channel_type: "channel",
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
await contains(".o-mail-Composer-suggestionList");
|
||||
await contains(".o-mail-Composer-suggestionList .o-open", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "" });
|
||||
await insertText(".o-mail-Composer-input", "bluhbluh ");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "bluhbluh " });
|
||||
await insertText(".o-mail-Composer-input", "/");
|
||||
// weak test, no guarantee that we waited long enough for the potential list to open
|
||||
await contains(".o-mail-Composer-suggestionList .o-open", 0);
|
||||
});
|
||||
|
||||
QUnit.test("Sort partner suggestions by recent chats", async (assert) => {
|
||||
const pyEnv = await startServer();
|
||||
|
||||
@@ -135,11 +135,7 @@ QUnit.test(
|
||||
await insertText(".o-discuss-ChannelSelector input", "131");
|
||||
await imSearchDef;
|
||||
});
|
||||
await contains(".o-discuss-ChannelSelector-suggestion a");
|
||||
const $link = $(".o-discuss-ChannelSelector-suggestion a");
|
||||
assert.strictEqual($link.text(), "Partner 131");
|
||||
|
||||
await click($link);
|
||||
await click(".o-discuss-ChannelSelector-suggestion a:contains(Partner 131)");
|
||||
await contains(".o-mail-ChatWindow-header:contains(New message)", 0);
|
||||
assert.strictEqual($(".o-mail-ChatWindow-name:eq(1)").text(), "Partner 131");
|
||||
}
|
||||
|
||||
@@ -82,11 +82,9 @@ QUnit.test("Channel mentions in the command palette of Discuss app with @", asyn
|
||||
await contains(
|
||||
".o_command_category:contains('Mentions') .o_command:contains('Mitchell Admin and Mario')"
|
||||
);
|
||||
await contains(".o_command_category:not(:contains('Mentions')) .o_command:contains('Mario')");
|
||||
await contains(
|
||||
$(".o_command_category:not(:contains('Mentions')) .o_command:contains('Mario')")
|
||||
);
|
||||
await contains(
|
||||
$(".o_command_category:not(:contains('Mentions')) .o_command:contains('Mitchell Admin')")
|
||||
".o_command_category:not(:contains('Mentions')) .o_command:contains('Mitchell Admin')"
|
||||
);
|
||||
await contains(".o_command.focused:contains('Mitchell Admin and Mario')");
|
||||
await click(".o_command.focused");
|
||||
|
||||
@@ -56,17 +56,17 @@ QUnit.test("can change the thread name of #general [REQUIRE FOCUS]", async (asse
|
||||
});
|
||||
openDiscuss(channelId);
|
||||
await contains(".o-mail-Composer-input:focus");
|
||||
assert.strictEqual((await contains("input.o-mail-Discuss-threadName")).val(), "general");
|
||||
await contains("input.o-mail-Discuss-threadName", 1, { value: "general" });
|
||||
await insertText("input.o-mail-Discuss-threadName:not(:disabled)", "special", {
|
||||
replace: true,
|
||||
});
|
||||
triggerHotkey("Enter");
|
||||
await contains(".o-mail-DiscussSidebarChannel:contains(special)");
|
||||
await contains($("input.o-mail-Discuss-threadName").filter((i, el) => el.value === "special"));
|
||||
await contains("input.o-mail-Discuss-threadName", 1, { value: "special" });
|
||||
assert.verifySteps(["/web/dataset/call_kw/discuss.channel/channel_rename"]);
|
||||
});
|
||||
|
||||
QUnit.test("can change the thread description of #general", async (assert) => {
|
||||
QUnit.test("can change the thread description of #general [REQUIRE FOCUS]", async (assert) => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({
|
||||
name: "general",
|
||||
@@ -83,21 +83,18 @@ QUnit.test("can change the thread description of #general", async (assert) => {
|
||||
});
|
||||
openDiscuss(channelId);
|
||||
await contains(".o-mail-Composer-input:focus");
|
||||
assert.strictEqual(
|
||||
(await contains("input.o-mail-Discuss-threadDescription")).val(),
|
||||
"General announcements..."
|
||||
);
|
||||
await contains("input.o-mail-Discuss-threadDescription", 1, {
|
||||
value: "General announcements...",
|
||||
});
|
||||
await insertText(
|
||||
"input.o-mail-Discuss-threadDescription:not(:disabled)",
|
||||
"I want a burger today!",
|
||||
{ replace: true }
|
||||
);
|
||||
triggerHotkey("Enter");
|
||||
await contains(
|
||||
$("input.o-mail-Discuss-threadDescription").filter(
|
||||
(i, el) => el.value === "I want a burger today!"
|
||||
)
|
||||
);
|
||||
await contains("input.o-mail-Discuss-threadDescription", 1, {
|
||||
value: "I want a burger today!",
|
||||
});
|
||||
assert.verifySteps(["/web/dataset/call_kw/discuss.channel/channel_change_description"]);
|
||||
});
|
||||
|
||||
@@ -168,7 +165,7 @@ QUnit.test(
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test("Click on avatar opens its partner chat window", async (assert) => {
|
||||
QUnit.test("Click on avatar opens its partner chat window", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const partnerId = pyEnv["res.partner"].create({ name: "testPartner" });
|
||||
pyEnv["res.users"].create({ partner_id: partnerId });
|
||||
@@ -183,8 +180,7 @@ QUnit.test("Click on avatar opens its partner chat window", async (assert) => {
|
||||
await openFormView("res.partner", partnerId);
|
||||
await contains(".o-mail-Message-sidebar .o-mail-Message-avatarContainer img");
|
||||
await click(".o-mail-Message-sidebar .o-mail-Message-avatarContainer img");
|
||||
await contains(".o-mail-ChatWindow-name");
|
||||
assert.ok($(".o-mail-ChatWindow-name").text().includes("testPartner"));
|
||||
await contains(".o-mail-ChatWindow-name:contains(testPartner)");
|
||||
});
|
||||
|
||||
QUnit.test("Can use channel command /who", async () => {
|
||||
@@ -435,24 +431,21 @@ QUnit.test("basic rendering", async () => {
|
||||
await contains(".o-mail-Discuss-content .o-mail-Thread");
|
||||
});
|
||||
|
||||
QUnit.test("basic rendering: sidebar", async (assert) => {
|
||||
QUnit.test("basic rendering: sidebar", async () => {
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss();
|
||||
await contains(".o-mail-DiscussSidebar button:contains(Inbox)");
|
||||
await contains(".o-mail-DiscussSidebar button:contains(Starred)");
|
||||
await contains(".o-mail-DiscussSidebar button:contains(History)");
|
||||
await contains(".o-mail-DiscussSidebarCategory", 2);
|
||||
await contains(".o-mail-DiscussSidebarCategory-channel");
|
||||
await contains(".o-mail-DiscussSidebarCategory-chat");
|
||||
assert.strictEqual($(".o-mail-DiscussSidebarCategory-channel").text(), "Channels");
|
||||
assert.strictEqual($(".o-mail-DiscussSidebarCategory-chat").text(), "Direct messages");
|
||||
await contains(".o-mail-DiscussSidebarCategory-channel:contains(Channels)");
|
||||
await contains(".o-mail-DiscussSidebarCategory-chat:contains(Direct messages)");
|
||||
});
|
||||
|
||||
QUnit.test("sidebar: Inbox should have icon", async (assert) => {
|
||||
QUnit.test("sidebar: Inbox should have icon", async () => {
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss();
|
||||
await contains("button:contains(Inbox)");
|
||||
assert.containsOnce($("button:contains(Inbox)"), ".fa-inbox");
|
||||
await contains("button:contains(Inbox) .fa-inbox");
|
||||
});
|
||||
|
||||
QUnit.test("sidebar: default active inbox", async () => {
|
||||
@@ -472,29 +465,19 @@ QUnit.test("sidebar: change active", async () => {
|
||||
await contains("button:contains(Starred).o-active");
|
||||
});
|
||||
|
||||
QUnit.test("sidebar: basic channel rendering", async (assert) => {
|
||||
QUnit.test("sidebar: basic channel rendering", async () => {
|
||||
const pyEnv = await startServer();
|
||||
pyEnv["discuss.channel"].create({ name: "General" });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss();
|
||||
await contains(".o-mail-DiscussSidebarChannel");
|
||||
assert.strictEqual($(".o-mail-DiscussSidebarChannel").text(), "General");
|
||||
assert.containsOnce($(".o-mail-DiscussSidebarChannel"), "img[data-alt='Thread Image']");
|
||||
assert.containsOnce(
|
||||
$(".o-mail-DiscussSidebarChannel"),
|
||||
".o-mail-DiscussSidebarChannel-commands"
|
||||
await contains(".o-mail-DiscussSidebarChannel:contains(General)");
|
||||
await contains(".o-mail-DiscussSidebarChannel img[data-alt='Thread Image']");
|
||||
await contains(".o-mail-DiscussSidebarChannel .o-mail-DiscussSidebarChannel-commands.d-none");
|
||||
await contains(
|
||||
".o-mail-DiscussSidebarChannel .o-mail-DiscussSidebarChannel-commands i[title='Channel settings']"
|
||||
);
|
||||
assert.hasClass(
|
||||
$(".o-mail-DiscussSidebarChannel .o-mail-DiscussSidebarChannel-commands"),
|
||||
"d-none"
|
||||
);
|
||||
assert.containsOnce(
|
||||
$(".o-mail-DiscussSidebarChannel .o-mail-DiscussSidebarChannel-commands"),
|
||||
"i[title='Channel settings']"
|
||||
);
|
||||
assert.containsOnce(
|
||||
$(".o-mail-DiscussSidebarChannel .o-mail-DiscussSidebarChannel-commands"),
|
||||
"div[title='Leave this channel']"
|
||||
await contains(
|
||||
".o-mail-DiscussSidebarChannel .o-mail-DiscussSidebarChannel-commands div[title='Leave this channel']"
|
||||
);
|
||||
});
|
||||
|
||||
@@ -591,21 +574,21 @@ QUnit.test("default active id on mailbox", async () => {
|
||||
await contains("button:contains(Starred).o-active");
|
||||
});
|
||||
|
||||
QUnit.test("basic top bar rendering", async (assert) => {
|
||||
QUnit.test("basic top bar rendering", async () => {
|
||||
const pyEnv = await startServer();
|
||||
pyEnv["discuss.channel"].create({ name: "General" });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss();
|
||||
await contains("button:contains(Mark all read):disabled");
|
||||
assert.strictEqual($(".o-mail-Discuss-threadName").val(), "Inbox");
|
||||
await contains(".o-mail-Discuss-threadName", 1, { value: "Inbox" });
|
||||
|
||||
await click("button:contains(Starred)");
|
||||
await contains("button:contains(Unstar all):disabled");
|
||||
assert.strictEqual($(".o-mail-Discuss-threadName").val(), "Starred");
|
||||
await contains(".o-mail-Discuss-threadName", 1, { value: "Starred" });
|
||||
|
||||
await click(".o-mail-DiscussSidebarChannel:contains(General)");
|
||||
await contains(".o-mail-Discuss-header button[title='Add Users']");
|
||||
assert.strictEqual($(".o-mail-Discuss-threadName").val(), "General");
|
||||
await contains(".o-mail-Discuss-threadName", 1, { value: "General" });
|
||||
});
|
||||
|
||||
QUnit.test("rendering of inbox message", async () => {
|
||||
@@ -846,16 +829,16 @@ QUnit.test("post a simple message", async (assert) => {
|
||||
openDiscuss(channelId);
|
||||
await contains(".o-mail-Thread:contains(There are no messages in this conversation.)");
|
||||
await contains(".o-mail-Message", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "" });
|
||||
|
||||
// insert some HTML in editable
|
||||
await insertText(".o-mail-Composer-input", "Test");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "Test");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "Test" });
|
||||
|
||||
await click(".o-mail-Composer-send:not(:disabled)");
|
||||
await contains(".o-mail-Message");
|
||||
assert.verifySteps(["message_post"]);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "" });
|
||||
pyEnv["mail.message"].search([], { order: "id DESC" });
|
||||
const $message = $(".o-mail-Message");
|
||||
await contains(".o-mail-Message:contains(Test)");
|
||||
@@ -873,14 +856,10 @@ QUnit.test("starred: unstar all", async (assert) => {
|
||||
openDiscuss("mail.box_starred");
|
||||
await contains(".o-mail-Message", 2);
|
||||
assert.strictEqual($("button:contains(Starred) .badge").text(), "2");
|
||||
let $unstarAll = $("button:contains(Unstar all)");
|
||||
assert.notOk($unstarAll[0].disabled);
|
||||
|
||||
await click($unstarAll);
|
||||
await click("button:contains(Unstar all):not(:disabled)");
|
||||
await contains("button:contains(Starred) .badge", 0);
|
||||
await contains(".o-mail-Message", 0);
|
||||
$unstarAll = $("button:contains(Unstar all)");
|
||||
assert.ok($unstarAll[0].disabled);
|
||||
await contains("button:contains(Unstar all):disabled");
|
||||
});
|
||||
|
||||
QUnit.test("auto-focus composer on opening thread", async (assert) => {
|
||||
@@ -1288,7 +1267,7 @@ QUnit.test(
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test("Channel is added to discuss after invitation", async (assert) => {
|
||||
QUnit.test("Channel is added to discuss after invitation", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const userId = pyEnv["res.users"].create({ name: "Harry" });
|
||||
const partnerId = pyEnv["res.partner"].create({ name: "Harry", user_ids: [userId] });
|
||||
@@ -1309,29 +1288,26 @@ QUnit.test("Channel is added to discuss after invitation", async (assert) => {
|
||||
await contains(".o_notification.border-info:contains(You have been invited to #General)");
|
||||
});
|
||||
|
||||
QUnit.test("select another mailbox", async (assert) => {
|
||||
QUnit.test("select another mailbox", async () => {
|
||||
patchUiSize({ height: 360, width: 640 });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss();
|
||||
await contains(".o-mail-Discuss");
|
||||
assert.strictEqual($(".o-mail-Discuss-threadName").val(), "Inbox");
|
||||
await contains(".o-mail-Discuss-threadName", 1, { value: "Inbox" });
|
||||
await click("button:contains(Starred)");
|
||||
await contains("button:contains(Unstar all):disabled");
|
||||
assert.strictEqual($(".o-mail-Discuss-threadName").val(), "Starred");
|
||||
await contains(".o-mail-Discuss-threadName", 1, { value: "Starred" });
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
'auto-select "Inbox nav bar" when discuss had inbox as active thread',
|
||||
async (assert) => {
|
||||
patchUiSize({ height: 360, width: 640 });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss();
|
||||
assert.strictEqual((await contains(".o-mail-Discuss-threadName")).val(), "Inbox");
|
||||
await contains(".o-mail-MessagingMenu-navbar:contains(Mailboxes) .fw-bolder");
|
||||
await contains("button:contains(Inbox).o-active");
|
||||
await contains("h4:contains(Congratulations, your inbox is empty)");
|
||||
}
|
||||
);
|
||||
QUnit.test('auto-select "Inbox nav bar" when discuss had inbox as active thread', async () => {
|
||||
patchUiSize({ height: 360, width: 640 });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss();
|
||||
await contains(".o-mail-Discuss-threadName", 1, { value: "Inbox" });
|
||||
await contains(".o-mail-MessagingMenu-navbar:contains(Mailboxes) .fw-bolder");
|
||||
await contains("button:contains(Inbox).o-active");
|
||||
await contains("h4:contains(Congratulations, your inbox is empty)");
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"composer should be focused automatically after clicking on the send button [REQUIRE FOCUS]",
|
||||
|
||||
@@ -44,7 +44,7 @@ QUnit.test("reply: discard on reply button toggle", async (assert) => {
|
||||
await contains(".o-mail-Composer", 0);
|
||||
});
|
||||
|
||||
QUnit.test("reply: discard on pressing escape", async (assert) => {
|
||||
QUnit.test("reply: discard on pressing escape", async () => {
|
||||
const pyEnv = await startServer();
|
||||
pyEnv["res.partner"].create({
|
||||
email: "testpartnert@odoo.com",
|
||||
|
||||
@@ -256,7 +256,7 @@ QUnit.test("sidebar: open pinned channel", async (assert) => {
|
||||
openDiscuss();
|
||||
await click(".o-mail-DiscussSidebarChannel:contains(General)");
|
||||
await contains(".o-mail-Composer-input[placeholder='Message #General…']");
|
||||
assert.strictEqual($(".o-mail-Discuss-threadName").val(), "General");
|
||||
await contains(".o-mail-Discuss-threadName", 1, { value: "General" });
|
||||
});
|
||||
|
||||
QUnit.test("sidebar: open channel and leave it", async (assert) => {
|
||||
@@ -286,10 +286,10 @@ QUnit.test("sidebar: open channel and leave it", async (assert) => {
|
||||
await click(".o-mail-DiscussSidebarChannel:contains(General) .btn[title='Leave this channel']");
|
||||
assert.verifySteps(["action_unfollow"]);
|
||||
await contains(".o-mail-DiscussSidebarChannel:contains(General)", 0);
|
||||
assert.notOk($(".o-mail-Discuss-threadName")?.val() === "General");
|
||||
await contains(".o-mail-Discuss-threadName", 0, { value: "General" });
|
||||
});
|
||||
|
||||
QUnit.test("sidebar: unpin channel from bus", async (assert) => {
|
||||
QUnit.test("sidebar: unpin channel from bus", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "General" });
|
||||
const { openDiscuss } = await start();
|
||||
@@ -298,13 +298,13 @@ QUnit.test("sidebar: unpin channel from bus", async (assert) => {
|
||||
|
||||
await click(".o-mail-DiscussSidebarChannel:contains(General)");
|
||||
await contains(".o-mail-Composer-input[placeholder='Message #General…']");
|
||||
assert.strictEqual($(".o-mail-Discuss-threadName").val(), "General");
|
||||
await contains(".o-mail-Discuss-threadName", 1, { value: "General" });
|
||||
|
||||
// Simulate receiving a leave channel notification
|
||||
// (e.g. from user interaction from another device or browser tab)
|
||||
pyEnv["bus.bus"]._sendone(pyEnv.currentPartner, "discuss.channel/unpin", { id: channelId });
|
||||
await contains(".o-mail-DiscussSidebarChannel:contains(General)", 0);
|
||||
assert.notOk($(".o-mail-Discuss-threadName")?.val() === "General");
|
||||
await contains(".o-mail-Discuss-threadName", 0, { value: "General" });
|
||||
});
|
||||
|
||||
QUnit.test("chat - channel should count unread message [REQUIRE FOCUS]", async (assert) => {
|
||||
|
||||
@@ -47,7 +47,7 @@ QUnit.test("Press Escape in emoji picker closes the emoji picker", async () => {
|
||||
await contains(".o-EmojiPicker", 0);
|
||||
});
|
||||
|
||||
QUnit.test("Basic keyboard navigation", async (assert) => {
|
||||
QUnit.test("Basic keyboard navigation", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "" });
|
||||
const { openDiscuss } = await start();
|
||||
@@ -65,7 +65,7 @@ QUnit.test("Basic keyboard navigation", async (assert) => {
|
||||
const codepoints = $(".o-EmojiPicker-content .o-Emoji[data-index=0].bg-200").data("codepoints");
|
||||
triggerHotkey("Enter");
|
||||
await contains(".o-EmojiPicker", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), codepoints);
|
||||
await contains(".o-mail-Composer-input", 1, { value: codepoints });
|
||||
});
|
||||
|
||||
QUnit.test("recent category (basic)", async () => {
|
||||
@@ -144,7 +144,7 @@ QUnit.test("first category should be highlighted by default", async () => {
|
||||
|
||||
QUnit.test(
|
||||
"selecting an emoji while holding down the Shift key prevents the emoji picker from closing",
|
||||
async (assert) => {
|
||||
async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "" });
|
||||
const { openDiscuss } = await start();
|
||||
@@ -155,6 +155,6 @@ QUnit.test(
|
||||
);
|
||||
await contains(".o-EmojiPicker-navbar [title='Frequently used']");
|
||||
await contains(".o-EmojiPicker");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "👺");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "👺" });
|
||||
}
|
||||
);
|
||||
|
||||
@@ -116,7 +116,7 @@ QUnit.test("Searching for a GIF", async () => {
|
||||
await contains(".o-discuss-Gif", 2);
|
||||
});
|
||||
|
||||
QUnit.test("Open a GIF category trigger the search for the category", async (assert) => {
|
||||
QUnit.test("Open a GIF category trigger the search for the category", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "" });
|
||||
const { openDiscuss } = await start({
|
||||
@@ -133,10 +133,7 @@ QUnit.test("Open a GIF category trigger the search for the category", async (ass
|
||||
await click("button[aria-label='GIFs']");
|
||||
await click("img[data-src='https://media.tenor.com/6uIlQAHIkNoAAAAM/cry.gif']");
|
||||
await contains(".o-discuss-Gif", 2);
|
||||
assert.strictEqual(
|
||||
document.querySelector("input[placeholder='Search for a gif']").value,
|
||||
"cry"
|
||||
);
|
||||
await contains("input[placeholder='Search for a gif']", 1, { value: "cry" });
|
||||
});
|
||||
|
||||
QUnit.test("Reopen GIF category list when going back", async () => {
|
||||
|
||||
@@ -608,31 +608,34 @@ export {
|
||||
startServer,
|
||||
};
|
||||
|
||||
/**
|
||||
* Waits until exactly one element matching the given selector is present in
|
||||
* `options.target` and then clicks on it.
|
||||
*
|
||||
* @param {string} selector
|
||||
* @param {Object} [options={}]
|
||||
* @param {HTMLElement} [options.target=document.body]
|
||||
*/
|
||||
export async function click(selector, { target = document.body } = {}) {
|
||||
if (typeof selector === "string") {
|
||||
const $e = await contains(selector, 1, { target });
|
||||
$e[0].click();
|
||||
return $($e[0]);
|
||||
} else if (selector instanceof HTMLElement) {
|
||||
selector.click();
|
||||
return Promise.resolve($(selector));
|
||||
} else {
|
||||
// jquery
|
||||
selector[0].click();
|
||||
return Promise.resolve($(selector[0]));
|
||||
}
|
||||
await contains(selector, 1, { click: true, target });
|
||||
}
|
||||
|
||||
let hasUsedContainsPositively = false;
|
||||
QUnit.testStart(() => (hasUsedContainsPositively = false));
|
||||
/**
|
||||
* Function that waits until a selector is present in the DOM.
|
||||
* Waits until `count` elements matching the given selector are present in
|
||||
* `options.target`.
|
||||
*
|
||||
* @param {string} selector
|
||||
* @param {number} [count=1]
|
||||
* @param {Object} [options={}]
|
||||
* @param {boolean} [options.click] if provided, clicks on the found element
|
||||
* @param {HTMLElement} [options.target=document.body]
|
||||
* @param {string} [options.value] if provided, the input value of the found element(s) must match.
|
||||
* Note: value changes are not observed directly, another mutation must happen to catch them.
|
||||
* @returns {Promise<JQuery<HTMLElement>>}
|
||||
*/
|
||||
export function contains(selector, count = 1, { target = document.body } = {}) {
|
||||
export function contains(selector, count = 1, { click, target = document.body, value } = {}) {
|
||||
if (count) {
|
||||
hasUsedContainsPositively = true;
|
||||
} else if (!hasUsedContainsPositively) {
|
||||
@@ -640,30 +643,29 @@ export function contains(selector, count = 1, { target = document.body } = {}) {
|
||||
`Starting a test with "contains" of count 0 for selector "${selector}" is useless because it might immediately resolve. Start the test by checking that an expected element actually exists.`
|
||||
);
|
||||
}
|
||||
const res = $(target).find(selector);
|
||||
const resMessage = `Found ${count} occurrence(s) of ${selector}`;
|
||||
if (res.length === count) {
|
||||
QUnit.assert.ok(true, resMessage);
|
||||
return Promise.resolve(res);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let selectorMessage = `${count} of "${selector}"`;
|
||||
if (value !== undefined) {
|
||||
selectorMessage = `${selectorMessage} with value "${value}"`;
|
||||
}
|
||||
const $res = select();
|
||||
if ($res.length === count) {
|
||||
execute($res, "immediately");
|
||||
return;
|
||||
}
|
||||
let done = false;
|
||||
const timer = setTimeout(() => {
|
||||
observer.disconnect();
|
||||
const res = $(target).find(selector);
|
||||
const message = `Waited 5 second for ${count} occurrence(s) of ${selector}. Found ${res.length} instead.`;
|
||||
clean();
|
||||
const $res = select();
|
||||
const message = `Waited 5 second for ${selectorMessage}. Found ${$res.length} instead.`;
|
||||
QUnit.assert.ok(false, message);
|
||||
reject(new Error(message));
|
||||
done = true;
|
||||
}, 5000);
|
||||
const observer = new MutationObserver(() => {
|
||||
const res = $(target).find(selector);
|
||||
if (res.length === count) {
|
||||
observer.disconnect();
|
||||
QUnit.assert.ok(true, resMessage);
|
||||
resolve(res);
|
||||
clearTimeout(timer);
|
||||
done = true;
|
||||
const $res = select();
|
||||
if ($res.length === count) {
|
||||
clean();
|
||||
execute($res, "after mutations");
|
||||
}
|
||||
});
|
||||
observer.observe(document.body, {
|
||||
@@ -673,14 +675,30 @@ export function contains(selector, count = 1, { target = document.body } = {}) {
|
||||
});
|
||||
registerCleanup(() => {
|
||||
if (!done) {
|
||||
observer.disconnect();
|
||||
const res = $(target).find(selector);
|
||||
const message = `Test ended while waiting for ${count} occurrence(s) of ${selector}. Found ${res.length} instead.`;
|
||||
clean();
|
||||
const $res = select();
|
||||
const message = `Test ended while waiting for ${selectorMessage}. Found ${$res.length} instead.`;
|
||||
QUnit.assert.ok(false, message);
|
||||
reject(new Error(message));
|
||||
clearTimeout(timer);
|
||||
done = true;
|
||||
}
|
||||
});
|
||||
function select() {
|
||||
const $res = $(target).find(selector);
|
||||
return value === undefined ? $res : $res.filter((i, el) => el.value === value);
|
||||
}
|
||||
function execute($res, whenMessage) {
|
||||
let message = `Found ${selectorMessage} (${whenMessage})`;
|
||||
if (click) {
|
||||
message = `${message} and clicked it`;
|
||||
$res[0].click();
|
||||
}
|
||||
QUnit.assert.ok(true, message);
|
||||
resolve($res);
|
||||
}
|
||||
function clean() {
|
||||
observer.disconnect();
|
||||
clearTimeout(timer);
|
||||
done = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ const { DateTime } = luxon;
|
||||
|
||||
QUnit.module("message");
|
||||
|
||||
QUnit.test("Start edition on click edit", async (assert) => {
|
||||
QUnit.test("Start edition on click edit", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({
|
||||
name: "general",
|
||||
@@ -40,8 +40,7 @@ QUnit.test("Start edition on click edit", async (assert) => {
|
||||
openDiscuss(channelId);
|
||||
await click(".o-mail-Message [title='Expand']");
|
||||
await click(".o-mail-Message [title='Edit']");
|
||||
await contains(".o-mail-Message-editable .o-mail-Composer");
|
||||
assert.strictEqual($(".o-mail-Message-editable .o-mail-Composer-input").val(), "Hello world");
|
||||
await contains(".o-mail-Message-editable .o-mail-Composer-input", 1, { value: "Hello world" });
|
||||
});
|
||||
|
||||
QUnit.test("Can edit message comment in chatter", async () => {
|
||||
@@ -344,14 +343,14 @@ QUnit.test("can add new mentions when editing message", async () => {
|
||||
await click(".o-mail-Message [title='Edit']");
|
||||
await insertText(".o-mail-Message .o-mail-Composer-input", " @");
|
||||
await click(".o-mail-Composer-suggestion:contains(TestPartner)");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "Hello @TestPartner " });
|
||||
await click(".o-mail-Message a:contains('save')");
|
||||
await contains(
|
||||
".o-mail-Message-body:contains(Hello @TestPartner) a.o_mail_redirect:contains(@TestPartner)"
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("Other messages are grayed out when replying to another one", async (assert) => {
|
||||
QUnit.test("Other messages are grayed out when replying to another one", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({
|
||||
channel_type: "channel",
|
||||
@@ -946,7 +945,7 @@ QUnit.test(
|
||||
await contains(".o-mail-Message");
|
||||
triggerHotkey("ArrowUp");
|
||||
await contains(".o-mail-Message .o-mail-Message-editable");
|
||||
assert.strictEqual($(".o-mail-Message .o-mail-Composer-input").val(), "not empty");
|
||||
await contains(".o-mail-Message .o-mail-Composer-input", 1, { value: "not empty" });
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1264,7 +1263,7 @@ QUnit.test("Chat with partner should be opened after clicking on their mention",
|
||||
await click("button:contains(Send message)");
|
||||
await insertText(".o-mail-Composer-input", "@Te");
|
||||
await click(".o-mail-Composer-suggestion:contains(Test Partner)");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "@Test Partner " });
|
||||
await click(".o-mail-Composer-send:not(:disabled)");
|
||||
await click(".o_mail_redirect");
|
||||
await contains(".o-mail-ChatWindow-content");
|
||||
|
||||
@@ -429,9 +429,7 @@ QUnit.test("different discuss.channel are not grouped", async () => {
|
||||
await start();
|
||||
await click(".o_menu_systray i[aria-label='Messages']");
|
||||
await contains(".o-mail-NotificationItem", 4);
|
||||
|
||||
const group_1 = $(".o-mail-NotificationItem:contains(Channel):first");
|
||||
await click(group_1);
|
||||
await click(".o-mail-NotificationItem:contains(Channel):first");
|
||||
await contains(".o-mail-ChatWindow");
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { patchWithCleanup, triggerEvent } from "@web/../tests/helpers/utils";
|
||||
|
||||
QUnit.module("notification");
|
||||
|
||||
QUnit.test("basic layout", async (assert) => {
|
||||
QUnit.test("basic layout", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({});
|
||||
const messageId = pyEnv["mail.message"].create({
|
||||
@@ -32,16 +32,15 @@ QUnit.test("basic layout", async (assert) => {
|
||||
await click(".o_menu_systray i[aria-label='Messages']");
|
||||
await contains(".o-mail-NotificationItem-name:contains(Channel)");
|
||||
await contains(".o-mail-NotificationItem-counter:contains(2)");
|
||||
assert.containsOnce(
|
||||
$(".o-mail-NotificationItem-name:contains(Channel)").closest(".o-mail-NotificationItem"),
|
||||
".o-mail-NotificationItem-date:contains(now)"
|
||||
await contains(
|
||||
".o-mail-NotificationItem:contains(Channel) .o-mail-NotificationItem-date:contains(now)"
|
||||
);
|
||||
await contains(
|
||||
".o-mail-NotificationItem-text:contains(An error occurred when sending an email)"
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("mark as read", async (assert) => {
|
||||
QUnit.test("mark as read", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({});
|
||||
const messageId = pyEnv["mail.message"].create({
|
||||
@@ -59,24 +58,13 @@ QUnit.test("mark as read", async (assert) => {
|
||||
await click(".o_menu_systray i[aria-label='Messages']");
|
||||
await triggerEvent(
|
||||
(
|
||||
await contains(".o-mail-NotificationItem-name:contains(Channel)")
|
||||
).closest(".o-mail-NotificationItem")[0],
|
||||
await contains(".o-mail-NotificationItem:contains(Channel)")
|
||||
)[0],
|
||||
null,
|
||||
"mouseenter"
|
||||
);
|
||||
assert.containsOnce(
|
||||
$(".o-mail-NotificationItem-name:contains(Channel)").closest(".o-mail-NotificationItem"),
|
||||
".o-mail-NotificationItem-markAsRead"
|
||||
);
|
||||
|
||||
await click(
|
||||
$(".o-mail-NotificationItem-name:contains(Channel)")
|
||||
.closest(".o-mail-NotificationItem")
|
||||
.find(".o-mail-NotificationItem-markAsRead")
|
||||
);
|
||||
assert.containsNone(
|
||||
$(".o-mail-NotificationItem-name:contains(Channel)").closest(".o-mail-NotificationItem")
|
||||
);
|
||||
await click(".o-mail-NotificationItem:contains(Channel) .o-mail-NotificationItem-markAsRead");
|
||||
await contains(".o-mail-NotificationItem:contains(Channel)", 0);
|
||||
});
|
||||
|
||||
QUnit.test("open non-channel failure", async (assert) => {
|
||||
@@ -136,7 +124,7 @@ QUnit.test("open non-channel failure", async (assert) => {
|
||||
assert.verifySteps(["do_action"]);
|
||||
});
|
||||
|
||||
QUnit.test("different discuss.channel are not grouped", async (assert) => {
|
||||
QUnit.test("different discuss.channel are not grouped", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const [channelId_1, channelId_2] = pyEnv["discuss.channel"].create([
|
||||
{ name: "Channel_1" },
|
||||
|
||||
@@ -38,9 +38,6 @@ QUnit.test('display partner mention suggestions on typing "@"', async () => {
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
await contains(".o-mail-Composer-input");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await contains(".o-mail-Composer-suggestion", 3);
|
||||
});
|
||||
@@ -69,7 +66,6 @@ QUnit.test(
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
await contains(".o-mail-Composer-input");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await insertText(".o-mail-Composer-input", "first message");
|
||||
await click("button:contains(Send):not(:disabled)");
|
||||
await contains(".o-mail-Message");
|
||||
@@ -83,7 +79,6 @@ QUnit.test('display partner mention suggestions on typing "@" in chatter', async
|
||||
const { openFormView } = await start();
|
||||
openFormView("res.partner", pyEnv.currentPartnerId);
|
||||
await click("button:contains(Send message)");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await contains(".o-mail-Composer-suggestion:contains(Mitchell Admin)");
|
||||
});
|
||||
@@ -107,7 +102,27 @@ QUnit.test("show other channel member in @ mention", async () => {
|
||||
await contains(".o-mail-Composer-suggestion:contains(TestPartner)");
|
||||
});
|
||||
|
||||
QUnit.test("select @ mention insert mention text in composer", async (assert) => {
|
||||
QUnit.test("select @ mention insert mention text in composer", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const partnerId = pyEnv["res.partner"].create({
|
||||
email: "testpartner@odoo.com",
|
||||
name: "TestPartner",
|
||||
});
|
||||
const channelId = pyEnv["discuss.channel"].create({
|
||||
name: "general",
|
||||
channel_member_ids: [
|
||||
Command.create({ partner_id: pyEnv.currentPartnerId }),
|
||||
Command.create({ partner_id: partnerId }),
|
||||
],
|
||||
});
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await click(".o-mail-Composer-suggestion:contains(TestPartner)");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "@TestPartner " });
|
||||
});
|
||||
|
||||
QUnit.test("select @ mention closes suggestions", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const partnerId = pyEnv["res.partner"].create({
|
||||
email: "testpartner@odoo.com",
|
||||
@@ -125,7 +140,6 @@ QUnit.test("select @ mention insert mention text in composer", async (assert) =>
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await click(".o-mail-Composer-suggestion:contains(TestPartner)");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val().trim(), "@TestPartner");
|
||||
});
|
||||
|
||||
QUnit.test('display channel mention suggestions on typing "#"', async () => {
|
||||
@@ -142,7 +156,7 @@ QUnit.test('display channel mention suggestions on typing "#"', async () => {
|
||||
await contains(".o-mail-Composer-suggestionList .o-open");
|
||||
});
|
||||
|
||||
QUnit.test("mention a channel", async (assert) => {
|
||||
QUnit.test("mention a channel", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({
|
||||
name: "General",
|
||||
@@ -152,15 +166,10 @@ QUnit.test("mention a channel", async (assert) => {
|
||||
openDiscuss(channelId);
|
||||
await contains(".o-mail-Composer-suggestionList");
|
||||
await contains(".o-mail-Composer-suggestionList .o-open", 0);
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "" });
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
assert.strictEqual(
|
||||
$(".o-mail-Composer-input").val().replace(/\s/, " "),
|
||||
"#General ",
|
||||
"mentioned channel + additional whitespace afterwards"
|
||||
);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "#General " });
|
||||
});
|
||||
|
||||
QUnit.test("Channel suggestions do not crash after rpc returns", async (assert) => {
|
||||
@@ -196,8 +205,7 @@ QUnit.test("Suggestions are shown after delimiter was used in text (@)", async (
|
||||
await contains(".o-mail-Composer-suggestion");
|
||||
await insertText(".o-mail-Composer-input", "NonExistingUser");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await insertText(".o-mail-Composer-input", " ");
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await insertText(".o-mail-Composer-input", " @");
|
||||
await contains(".o-mail-Composer-suggestion:contains(Mitchell Admin)");
|
||||
});
|
||||
|
||||
@@ -210,8 +218,7 @@ QUnit.test("Suggestions are shown after delimiter was used in text (#)", async (
|
||||
await contains(".o-mail-Composer-suggestion");
|
||||
await insertText(".o-mail-Composer-input", "NonExistingChannel");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await insertText(".o-mail-Composer-input", " ");
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await insertText(".o-mail-Composer-input", " #");
|
||||
await contains(".o-mail-Composer-suggestion:contains(General)");
|
||||
});
|
||||
|
||||
@@ -234,7 +241,6 @@ QUnit.test("display partner mention when typing more than 2 words if they match"
|
||||
const { openFormView } = await start();
|
||||
openFormView("res.partner", pyEnv.currentPartnerId);
|
||||
await click("button:contains(Send message)");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await insertText(".o-mail-Composer-input", "@My ");
|
||||
await contains(".o-mail-Composer-suggestion", 3);
|
||||
await insertText(".o-mail-Composer-input", "Test ");
|
||||
|
||||
@@ -226,30 +226,28 @@ QUnit.test("thread is still scrolling after scrolling up then to bottom", async
|
||||
assert.ok(isScrolledToBottom($(".o-mail-Thread")[0]));
|
||||
});
|
||||
|
||||
QUnit.test("mention a channel with space in the name", async (assert) => {
|
||||
QUnit.test("mention a channel with space in the name", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "General good boy" });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "#General good boy " });
|
||||
await click(".o-mail-Composer-send:not(:disabled)");
|
||||
await contains(".o-mail-Message-body .o_channel_redirect");
|
||||
assert.strictEqual($(".o_channel_redirect").text(), "#General good boy");
|
||||
await contains(".o-mail-Message-body .o_channel_redirect:contains(#General good boy)");
|
||||
});
|
||||
|
||||
QUnit.test('mention a channel with "&" in the name', async (assert) => {
|
||||
QUnit.test('mention a channel with "&" in the name', async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "General & good" });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "#General & good " });
|
||||
await click(".o-mail-Composer-send:not(:disabled)");
|
||||
await contains(".o-mail-Message-body .o_channel_redirect");
|
||||
assert.strictEqual($(".o_channel_redirect").text(), "#General & good");
|
||||
await contains(".o-mail-Message-body .o_channel_redirect:contains(#General & good)");
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
@@ -571,7 +569,7 @@ QUnit.test("no new messages separator on posting message (no message history)",
|
||||
await contains("hr + span:contains(New messages)", 0);
|
||||
});
|
||||
|
||||
QUnit.test("Mention a partner with special character (e.g. apostrophe ')", async (assert) => {
|
||||
QUnit.test("Mention a partner with special character (e.g. apostrophe ')", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const partnerId = pyEnv["res.partner"].create({
|
||||
email: "usatyi@example.com",
|
||||
@@ -589,7 +587,7 @@ QUnit.test("Mention a partner with special character (e.g. apostrophe ')", async
|
||||
await insertText(".o-mail-Composer-input", "@");
|
||||
await insertText(".o-mail-Composer-input", "Pyn");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "@Pynya's spokesman " });
|
||||
await click(".o-mail-Composer-send:not(:disabled)");
|
||||
await contains(
|
||||
`.o-mail-Message-body .o_mail_redirect[data-oe-id="${partnerId}"][data-oe-model="res.partner"]:contains("@Pynya's spokesman")`
|
||||
@@ -620,10 +618,10 @@ QUnit.test("mention 2 different partners that have the same name", async () => {
|
||||
openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "@Te");
|
||||
await click(".o-mail-Composer-suggestion:eq(0)");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "@TestPartner " });
|
||||
await insertText(".o-mail-Composer-input", "@Te");
|
||||
await click(".o-mail-Composer-suggestion:eq(1)");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "@TestPartner @TestPartner " });
|
||||
await click(".o-mail-Composer-send:not(:disabled)");
|
||||
await contains(
|
||||
`.o-mail-Message-body .o_mail_redirect[data-oe-id="${partnerId_1}"][data-oe-model="res.partner"]:contains("@TestPartner")`
|
||||
@@ -633,17 +631,16 @@ QUnit.test("mention 2 different partners that have the same name", async () => {
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("mention a channel on a second line when the first line contains #", async (assert) => {
|
||||
QUnit.test("mention a channel on a second line when the first line contains #", async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "General good" });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "#blabla\n#");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "#blabla\n#General good " });
|
||||
await click(".o-mail-Composer-send:not(:disabled)");
|
||||
await contains(".o-mail-Message-body .o_channel_redirect");
|
||||
assert.strictEqual($(".o_channel_redirect").text(), "#General good");
|
||||
await contains(".o-mail-Message-body .o_channel_redirect:contains(#General good)");
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
@@ -655,7 +652,7 @@ QUnit.test(
|
||||
openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "#");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "#General good " });
|
||||
const text = $(".o-mail-Composer-input").val();
|
||||
$(".o-mail-Composer-input").val(text.slice(0, -1));
|
||||
await insertText(".o-mail-Composer-input", ", test");
|
||||
@@ -681,10 +678,10 @@ QUnit.test("mention 2 different channels that have the same name", async () => {
|
||||
openDiscuss(channelId_1);
|
||||
await insertText(".o-mail-Composer-input", "#m");
|
||||
await click(".o-mail-Composer-suggestion:eq(0)");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "#my channel " });
|
||||
await insertText(".o-mail-Composer-input", "#m");
|
||||
await click(".o-mail-Composer-suggestion:eq(1)");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "#my channel #my channel " });
|
||||
await click(".o-mail-Composer-send:not(:disabled)");
|
||||
await contains(
|
||||
`.o-mail-Message-body .o_channel_redirect[data-oe-id="${channelId_1}"][data-oe-model="discuss.channel"]:contains("#my channel")`
|
||||
@@ -713,7 +710,7 @@ QUnit.test(
|
||||
openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "email@odoo.com\n@Te");
|
||||
await click(".o-mail-Composer-suggestion");
|
||||
await contains(".o-mail-Composer-suggestion", 0);
|
||||
await contains(".o-mail-Composer-input", 1, { value: "email@odoo.com\n@TestPartner " });
|
||||
await click(".o-mail-Composer-send:not(:disabled)");
|
||||
await contains(
|
||||
`.o-mail-Message-body .o_mail_redirect[data-oe-id="${partnerId}"][data-oe-model="res.partner"]:contains("@TestPartner")`
|
||||
@@ -801,14 +798,14 @@ QUnit.test(
|
||||
|
||||
QUnit.test(
|
||||
"composer should be focused automatically after clicking on the send button",
|
||||
async (assert) => {
|
||||
async () => {
|
||||
const pyEnv = await startServer();
|
||||
const channelId = pyEnv["discuss.channel"].create({ name: "test" });
|
||||
const { openDiscuss } = await start();
|
||||
openDiscuss(channelId);
|
||||
await insertText(".o-mail-Composer-input", "Dummy Message");
|
||||
await click(".o-mail-Composer-send:not(:disabled)");
|
||||
assert.strictEqual(document.activeElement, $(".o-mail-Composer-input")[0]);
|
||||
await contains(".o-mail-Composer-input:focus");
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ QUnit.test("Composer toggle state is kept when switching from aside to bottom",
|
||||
await contains(".o-mail-Form-chatter:not(.o-aside) .o-mail-Composer-input");
|
||||
});
|
||||
|
||||
QUnit.test("Textarea content is kept when switching from aside to bottom", async (assert) => {
|
||||
QUnit.test("Textarea content is kept when switching from aside to bottom", async () => {
|
||||
patchUiSize({ size: SIZES.XXL });
|
||||
const { openFormView, pyEnv } = await start();
|
||||
const partnerId = pyEnv["res.partner"].create({ name: "John Doe" });
|
||||
@@ -175,7 +175,7 @@ QUnit.test("Textarea content is kept when switching from aside to bottom", async
|
||||
patchUiSize({ size: SIZES.LG });
|
||||
window.dispatchEvent(new Event("resize"));
|
||||
await contains(".o-mail-Form-chatter:not(.o-aside) .o-mail-Composer-input");
|
||||
assert.strictEqual($(".o-mail-Composer-input").val(), "Hello world !");
|
||||
await contains(".o-mail-Composer-input", 1, { value: "Hello world !" });
|
||||
});
|
||||
|
||||
QUnit.test("Composer type is kept when switching from aside to bottom", async (assert) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* @odoo-module */
|
||||
|
||||
import { start, startServer } from "@mail/../tests/helpers/test_utils";
|
||||
import { contains, start, startServer } from "@mail/../tests/helpers/test_utils";
|
||||
import {
|
||||
click,
|
||||
patchWithCleanup,
|
||||
@@ -125,7 +125,7 @@ QUnit.test(
|
||||
view_mode: "form",
|
||||
views: [[false, "form"]],
|
||||
});
|
||||
assert.strictEqual($(".o_field_many2one_avatar_user input").val(), "Mario");
|
||||
await contains(".o_field_many2one_avatar_user input", 1, { value: "Mario" });
|
||||
|
||||
triggerHotkey("control+k");
|
||||
await nextTick();
|
||||
@@ -142,7 +142,7 @@ QUnit.test(
|
||||
);
|
||||
await click(document.body, "#o_command_3");
|
||||
await nextTick();
|
||||
assert.strictEqual($(".o_field_many2one_avatar_user input").val(), "Luigi");
|
||||
await contains(".o_field_many2one_avatar_user input", 1, { value: "Luigi" });
|
||||
}
|
||||
);
|
||||
|
||||
@@ -169,7 +169,7 @@ QUnit.test(
|
||||
view_mode: "form",
|
||||
views: [[false, "form"]],
|
||||
});
|
||||
assert.strictEqual($(".o_field_many2one_avatar_user input").val(), "Mario");
|
||||
await contains(".o_field_many2one_avatar_user input", 1, { value: "Mario" });
|
||||
triggerHotkey("control+k");
|
||||
await nextTick();
|
||||
const idx = [...document.querySelectorAll(".o_command")]
|
||||
@@ -180,14 +180,14 @@ QUnit.test(
|
||||
// Assign me (Luigi)
|
||||
triggerHotkey("alt+shift+i");
|
||||
await nextTick();
|
||||
assert.strictEqual($(".o_field_many2one_avatar_user input").val(), "Luigi");
|
||||
await contains(".o_field_many2one_avatar_user input", 1, { value: "Luigi" });
|
||||
|
||||
// Unassign me
|
||||
triggerHotkey("control+k");
|
||||
await nextTick();
|
||||
await click([...document.querySelectorAll(".o_command")][idx]);
|
||||
await nextTick();
|
||||
assert.strictEqual($(".o_field_many2one_avatar_user input").val(), "");
|
||||
await contains(".o_field_many2one_avatar_user input", 1, { value: "" });
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/* @odoo-module */
|
||||
|
||||
import { start, startServer } from "@mail/../tests/helpers/test_utils";
|
||||
import { click, contains, insertText, start, startServer } from "@mail/../tests/helpers/test_utils";
|
||||
|
||||
import { selectDropdownItem } from "@web/../tests/helpers/utils";
|
||||
import testUtils from "@web/../tests/legacy/helpers/test_utils";
|
||||
|
||||
QUnit.module("FieldMany2ManyTagsEmail");
|
||||
|
||||
@@ -61,24 +60,13 @@ QUnit.test("fieldmany2many tags email (edition)", async (assert) => {
|
||||
".modal-content .o_form_view",
|
||||
"there should be one modal opened to edit the empty email"
|
||||
);
|
||||
assert.strictEqual(
|
||||
$(".modal-content .o_form_view .o_input#name_0").val(),
|
||||
"silver",
|
||||
"the opened modal in edit mode should be a form view dialog with the res.partner 14"
|
||||
);
|
||||
await contains(".modal-content .o_form_view .o_input#name_0", 1, { value: "silver" });
|
||||
assert.containsOnce($, ".modal-content .o_form_view .o_input#email_0");
|
||||
|
||||
// set the email and save the modal (will rerender the form view)
|
||||
await testUtils.fields.editInput(
|
||||
$(".modal-content .o_form_view .o_input#email_0"),
|
||||
"coucou@petite.perruche"
|
||||
);
|
||||
await testUtils.dom.click($(".modal-content .o_form_button_save"));
|
||||
assert.containsN(
|
||||
$,
|
||||
'.o_field_many2many_tags_email[name="partner_ids"] .badge.o_tag_color_0',
|
||||
2
|
||||
);
|
||||
await insertText(".modal-content .o_form_view .o_input#email_0", "coucou@petite.perruche");
|
||||
await click(".modal-content .o_form_button_save");
|
||||
await contains('.o_field_many2many_tags_email[name="partner_ids"] .badge.o_tag_color_0', 2);
|
||||
const firstTag = $('.o_field_many2many_tags_email[name="partner_ids"] .badge.o_tag_color_0')[0];
|
||||
assert.strictEqual(
|
||||
firstTag.querySelector(".o_badge_text").innerText,
|
||||
|
||||
@@ -40,9 +40,7 @@ QUnit.test("simplest layout of a followed subtype", async () => {
|
||||
`.o-mail-FollowerSubtypeDialog-subtype[data-follower-subtype-id=${subtypeId}] label:contains(TestSubtype)`
|
||||
);
|
||||
await contains(
|
||||
$(
|
||||
`.o-mail-FollowerSubtypeDialog-subtype[data-follower-subtype-id=${subtypeId}] input[type='checkbox']:checked`
|
||||
)
|
||||
`.o-mail-FollowerSubtypeDialog-subtype[data-follower-subtype-id=${subtypeId}] input[type='checkbox']:checked`
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ QUnit.test("remove a follower in a dirty form view", async (assert) => {
|
||||
await click(".o-mail-Followers-button");
|
||||
await click("button[title='Remove this follower']");
|
||||
await contains(".o-mail-Followers-counter:contains(0)");
|
||||
assert.strictEqual($(".o_field_char[name=name] input").val(), "some value");
|
||||
await contains(".o_field_char[name=name] input", 1, { value: "some value" });
|
||||
await contains(".o_tag:contains(General)");
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/** @odoo-module **/
|
||||
/* @odoo-module */
|
||||
|
||||
import { ActivityModel } from "@mail/views/web/activity/activity_model";
|
||||
import { ActivityRenderer } from "@mail/views/web/activity/activity_renderer";
|
||||
@@ -37,7 +37,7 @@ QUnit.module("test_mail", {}, function () {
|
||||
const mailActivityIds = pyEnv["mail.activity"].create([
|
||||
{
|
||||
display_name: "An activity",
|
||||
date_deadline: serializeDate(DateTime.now().plus({days:3})),
|
||||
date_deadline: serializeDate(DateTime.now().plus({ days: 3 })),
|
||||
can_write: true,
|
||||
state: "planned",
|
||||
activity_type_id: mailActivityTypeIds[0],
|
||||
@@ -56,7 +56,7 @@ QUnit.module("test_mail", {}, function () {
|
||||
{
|
||||
res_model: "mail.test.activity",
|
||||
display_name: "An activity",
|
||||
date_deadline: serializeDate(DateTime.now().minus({days:2})),
|
||||
date_deadline: serializeDate(DateTime.now().minus({ days: 2 })),
|
||||
can_write: true,
|
||||
state: "overdue",
|
||||
activity_type_id: mailActivityTypeIds[1],
|
||||
@@ -228,7 +228,7 @@ QUnit.module("test_mail", {}, function () {
|
||||
for (let i = 0; i < 81; i++) {
|
||||
activityToCreate.push({
|
||||
display_name: "An activity " + i,
|
||||
date_deadline: serializeDate(DateTime.now().plus({days:3})),
|
||||
date_deadline: serializeDate(DateTime.now().plus({ days: 3 })),
|
||||
can_write: true,
|
||||
state: "planned",
|
||||
activity_type_id: mailActivityTypeIds[0],
|
||||
@@ -827,13 +827,13 @@ QUnit.module("test_mail", {}, function () {
|
||||
pyEnv["mail.activity"].create([
|
||||
{
|
||||
display_name: "An activity",
|
||||
date_deadline: serializeDate(DateTime.now().plus({days:3})),
|
||||
date_deadline: serializeDate(DateTime.now().plus({ days: 3 })),
|
||||
can_write: true,
|
||||
state: "planned",
|
||||
activity_type_id: mailActivityTypeIds[2],
|
||||
mail_template_ids: mailTemplateIds,
|
||||
user_id: resUsersId1,
|
||||
}
|
||||
},
|
||||
]);
|
||||
const mailActivityIds = pyEnv["mail.activity"].search([]);
|
||||
const [mailTestActivityId1] = pyEnv["mail.test.activity"].search([
|
||||
@@ -885,7 +885,11 @@ QUnit.module("test_mail", {}, function () {
|
||||
".o_activity_filter_planned",
|
||||
"planned should be active filter"
|
||||
);
|
||||
assert.hasClass(target.querySelector(".o_activity_type_cell:nth-child(2) .bg-success"), "progress-bar-animated progress-bar-striped", "progress bar is animated with a strip effect");
|
||||
assert.hasClass(
|
||||
target.querySelector(".o_activity_type_cell:nth-child(2) .bg-success"),
|
||||
"progress-bar-animated progress-bar-striped",
|
||||
"progress bar is animated with a strip effect"
|
||||
);
|
||||
assert.containsOnce(target, ".progress-bar-striped", "only one progress bar is animated");
|
||||
assert.containsN(
|
||||
document.querySelector(".o_activity_view tbody"),
|
||||
@@ -1063,20 +1067,23 @@ QUnit.module("test_mail", {}, function () {
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test("test node is not displayed with invisible attribute on node", async function (assert) {
|
||||
const { target, openView } = await start({
|
||||
serverData,
|
||||
});
|
||||
await openView({
|
||||
res_model: "mail.test.activity",
|
||||
views: [[1, "activity"]],
|
||||
context: { invisible: true },
|
||||
});
|
||||
QUnit.test(
|
||||
"test node is not displayed with invisible attribute on node",
|
||||
async function (assert) {
|
||||
const { target, openView } = await start({
|
||||
serverData,
|
||||
});
|
||||
await openView({
|
||||
res_model: "mail.test.activity",
|
||||
views: [[1, "activity"]],
|
||||
context: { invisible: true },
|
||||
});
|
||||
|
||||
assert.containsNone(
|
||||
target,
|
||||
".invisible_node",
|
||||
"The node with the invisible attribute should be displayed since `invisible` key in the context contains truly value"
|
||||
);
|
||||
});
|
||||
assert.containsNone(
|
||||
target,
|
||||
".invisible_node",
|
||||
"The node with the invisible attribute should be displayed since `invisible` key in the context contains truly value"
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user