19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:31:39 +01:00
parent 5df8c07b59
commit daa394e8b0
2114 changed files with 564841 additions and 299642 deletions

View file

@ -0,0 +1,40 @@
/** @odoo-module **/
import { registry } from "@web/core/registry";
registry.category("web_tour.tours").add("change_chatbot_step_type", {
steps: () => [
{
content: "Open an existing script",
trigger: ".o_field_cell[data-tooltip='Clear Answer Test Bot']",
run: "click",
},
{
content: "Open first step",
trigger: '.o_row_draggable .o_field_cell:contains("Question")',
run: "click",
},
{
content: "Change step type to 'text'",
trigger: 'div[name="step_type"] input',
run: "click",
},
{
trigger: '.dropdown-item:contains("Text")',
run: "click",
},
{
content: "Verify answers cleared",
trigger: ".btn-primary:contains('Save')",
run: "click",
},
{
trigger: ".o_form_button_save",
run: "click",
},
{
// Ensure form is properly saved, in which case the save button is hidden.
trigger: ".o_form_button_save:not(:visible)",
},
],
});

View file

@ -1,32 +1,32 @@
/** @odoo-module */
import tour from "web_tour.tour";
import { registry } from "@web/core/registry";
const requestChatSteps = [
{
trigger: ".o_livechat_button",
trigger: ".o-livechat-root:shadow .o-livechat-LivechatButton",
run: "click",
},
{
trigger: ".o_thread_window",
trigger: ".o-livechat-root:shadow .o-mail-ChatWindow",
},
];
tour.register("im_livechat_request_chat", { test: true }, requestChatSteps);
registry.category("web_tour.tours").add("im_livechat_request_chat", {
steps: () => requestChatSteps,
});
tour.register("im_livechat_request_chat_and_send_message", { test: true }, [
...requestChatSteps,
{
trigger: ".o_composer_text_field",
run: "text Hello, I need help please !",
},
{
trigger: '.o_composer_text_field',
run() {
$(".o_composer_text_field").trigger($.Event("keydown", { which: 13 }));
registry.category("web_tour.tours").add("im_livechat_request_chat_and_send_message", {
steps: () => [
...requestChatSteps,
{
trigger: ".o-livechat-root:shadow .o-mail-Composer-input",
run: "edit Hello, I need help please !",
},
},
{
trigger: ".o_thread_message:contains('Hello, I need help')",
},
]);
{
trigger: ".o-livechat-root:shadow .o-mail-Composer-input",
run: "press Enter",
},
{
trigger: ".o-livechat-root:shadow .o-mail-Message:contains('Hello, I need help')",
},
],
});

View file

@ -1,130 +1,99 @@
/** @odoo-module */
import { registry } from "@web/core/registry";
import { stepUtils } from "@web_tour/tour_utils";
import tour from "web_tour.tour";
const commonSteps = [tour.stepUtils.showAppsMenuItem(), {
trigger: '.o_app[data-menu-xmlid="im_livechat.menu_livechat_root"]',
}, {
trigger: 'button[data-menu-xmlid="im_livechat.livechat_config"]',
}, {
trigger: 'a[data-menu-xmlid="im_livechat.chatbot_config"]',
}, {
trigger: '.o_list_button_add',
}, {
trigger: 'input[id="title"]',
run: 'text Test Chatbot Sequence'
}, {
trigger: 'div[name="script_step_ids"] .o_field_x2many_list_row_add a'
}, {
trigger: 'textarea#message',
run: 'text Step 1'
}, {
trigger: 'button:contains("Save & New")'
}, {
trigger: 'tr:contains("Step 1")',
in_modal: false,
run: () => {}
}, {
trigger: 'textarea#message',
run: 'text Step 2'
}, {
trigger: 'button:contains("Save & New")'
}, {
trigger: 'tr:contains("Step 2")',
in_modal: false,
run: () => {}
}, {
trigger: 'textarea#message',
run: 'text Step 3'
}];
function createChatbotSteps(...stepMessages) {
return [
{
trigger: "div[name='script_step_ids'] .o_field_x2many_list_row_add a",
run: "click",
},
...stepMessages
.map((message) => [
{
trigger: ".modal .odoo-editor-editable",
run: `editor ${message}`,
},
{
trigger: `.modal .odoo-editor-editable:contains(${message})`,
},
{
trigger: ".modal button:contains(Save & New)",
run: "click",
},
{
trigger: `tr:contains(${message})`,
},
{
trigger: ".modal .odoo-editor-editable:empty",
},
])
.flat(),
{
trigger: ".modal-footer button:contains(Discard)",
run: "click",
},
];
}
const commonSteps = [
stepUtils.showAppsMenuItem(),
{
trigger: '.o_app[data-menu-xmlid="im_livechat.menu_livechat_root"]',
run: "click",
},
{
trigger: 'button[data-menu-xmlid="im_livechat.livechat_config"]',
run: "click",
},
{
trigger: 'a[data-menu-xmlid="im_livechat.chatbot_config"]',
run: "click",
},
{
trigger: ".o_list_button_add",
run: "click",
},
{
trigger: 'input[id="title_0"]',
run: "edit Test Chatbot Sequence",
},
...createChatbotSteps("Step 1", "Step 2", "Step 3"),
];
/**
* Simply create a few steps in order to check the sequences.
*/
tour.register('im_livechat_chatbot_steps_sequence_tour', {
test: true,
url: '/web',
}, [
...commonSteps, {
trigger: 'button:contains("Save & Close")'
}, {
trigger: 'body.o_web_client:not(.modal-open)',
run() {},
}, ...tour.stepUtils.discardForm()
]);
registry.category("web_tour.tours").add("im_livechat_chatbot_steps_sequence_tour", {
url: "/odoo",
steps: () => [
...commonSteps,
{
trigger: "body.o_web_client:not(.modal-open)",
},
],
});
/**
* Same as above, with an extra drag&drop at the end.
*/
tour.register('im_livechat_chatbot_steps_sequence_with_move_tour', {
test: true,
url: '/web',
}, [
...commonSteps, {
trigger: 'button:contains("Save & New")'
}, {
trigger: 'tr:contains("Step 3")',
in_modal: false,
run: () => {}
}, {
trigger: 'textarea#message',
run: 'text Step 4'
}, {
trigger: 'button:contains("Save & New")'
}, {
trigger: 'tr:contains("Step 4")',
in_modal: false,
run: () => {}
}, {
trigger: 'textarea#message',
run: 'text Step 5'
}, {
trigger: 'button:contains("Save & Close")'
}, {
trigger: 'body.o_web_client:not(.modal-open)',
run: () => {}
}, {
trigger: 'tr:contains("Step 5") .o_row_handle',
run: () => {
// move 'step 5' between 'step 1' and 'step 2'
const from = document.querySelector('div[name="script_step_ids"] tr:nth-child(5) .o_row_handle');
const fromPosition = from.getBoundingClientRect();
fromPosition.x += from.offsetWidth / 2;
fromPosition.y += from.offsetHeight / 2;
const to = document.querySelector('div[name="script_step_ids"] tr:nth-child(2) .o_row_handle');
from.dispatchEvent(new Event("mouseenter", { bubbles: true }));
from.dispatchEvent(new MouseEvent("mousedown", {
bubbles: true,
which: 1,
button: 0,
clientX: fromPosition.x,
clientY: fromPosition.y}));
from.dispatchEvent(new MouseEvent("mousemove", {
bubbles: true,
which: 1,
button: 0,
// dragging is only enabled when the mouse have moved from at least 10 pixels from the original position
clientX: fromPosition.x + 20,
clientY: fromPosition.y + 20,
}));
to.dispatchEvent(new Event("mouseenter", { bubbles: true }));
from.dispatchEvent(new Event("mouseup", { bubbles: true }));
}
}, {
trigger: 'div[name="script_step_ids"] .o_field_x2many_list_row_add a'
}, {
trigger: 'textarea#message',
run: 'text Step 6'
}, {
trigger: 'button:contains("Save & Close")'
}, {
trigger: 'body.o_web_client:not(.modal-open)',
run: () => {}
}, {
trigger: 'tr:contains("Step 6")',
in_modal: false,
run: () => {}
}, ...tour.stepUtils.discardForm(),
]);
registry.category("web_tour.tours").add("im_livechat_chatbot_steps_sequence_with_move_tour", {
url: "/odoo",
steps: () => [
...commonSteps,
...createChatbotSteps("Step 4", "Step 5"),
{
trigger: "body.o_web_client:not(.modal-open)",
},
{
trigger: 'div[name="script_step_ids"] tr:nth-child(5) .o_row_handle',
run: 'drag_and_drop(div[name="script_step_ids"] tr:nth-child(2))',
},
...createChatbotSteps("Step 6"),
{
trigger: "body.o_web_client:not(.modal-open)",
},
{
trigger: 'tr:contains("Step 6")',
},
],
});

View file

@ -0,0 +1,39 @@
import { delay } from "@web/core/utils/concurrency";
import { registry } from "@web/core/registry";
registry.category("web_tour.tours").add("im_livechat_history_back_and_forth_tour", {
steps: () => [
{
trigger: "button.o_switch_view.o_list",
run: "click",
},
{
trigger: ".o_data_cell:contains(Visitor)",
run: "click",
},
{
trigger: ".o-mail-DiscussContent-threadName[title='Visitor']",
async run() {
await delay(1000);
history.back();
},
},
{
trigger: ".o_data_cell:contains(Visitor)",
async run() {
await delay(0);
history.forward();
},
},
{
trigger: ".o-mail-DiscussContent-threadName[title='Visitor']",
async run() {
await delay(1000);
history.back();
},
},
{
trigger: ".o_data_cell:contains(Visitor)",
},
],
});

View file

@ -0,0 +1,56 @@
import { registry } from "@web/core/registry";
/**
* @param {"list" | "kanban"} viewType
* @returns {import("@web_tour/tour_service/tour_service").TourStep[]}
*/
function getSteps(viewType) {
let bobChatId;
return [
{
trigger: ".o_control_panel .active:contains(Looking for Help)",
},
{
trigger:
viewType === "list"
? ".o_list_table:has(.o_data_row:contains(bob_looking_for_help))"
: ".o_kanban_renderer:has(.o_kanban_record [name=livechat_agent_partner_ids] [aria-label^=bob_looking_for_help])",
async run() {
const { orm } = odoo.__WOWL_DEBUG__.root.env.services;
[bobChatId] = await orm.search("discuss.channel", [
["livechat_status", "=", "need_help"],
["livechat_agent_partner_ids.name", "like", "bob_looking_for_help%"],
]);
await orm.write("discuss.channel", [bobChatId], {
livechat_status: "in_progress",
});
},
},
{
trigger:
viewType === "list"
? ".o_list_table:not(:has(.o_data_row:contains(bob_looking_for_help)))"
: ".o_kanban_renderer:not(:has(.o_kanban_record [name=livechat_agent_partner_ids] [aria-label^=bob_looking_for_help]))",
async run() {
const { orm } = odoo.__WOWL_DEBUG__.root.env.services;
await orm.write("discuss.channel", [bobChatId], {
livechat_status: "need_help",
});
},
},
{
trigger:
viewType === "list"
? ".o_list_table:has(.o_data_row:contains(bob_looking_for_help))"
: ".o_kanban_renderer:has(.o_kanban_record [name=livechat_agent_partner_ids] [aria-label^=bob_looking_for_help])",
},
];
}
registry.category("web_tour.tours").add("im_livechat.looking_for_help_list_real_time_update_tour", {
steps: () => getSteps("list"),
});
registry
.category("web_tour.tours")
.add("im_livechat.looking_for_help_kanban_real_time_update_tour", {
steps: () => getSteps("kanban"),
});

View file

@ -0,0 +1,57 @@
import { registry } from "@web/core/registry";
import { rpc } from "@web/core/network/rpc";
let bobChatId;
let tagId;
registry.category("web_tour.tours").add("im_livechat.looking_for_help_tags_real_time_update_tour", {
steps: () => [
{
trigger: ".o_control_panel .active:contains(Looking for Help)",
},
{
trigger: ".o_optional_columns_dropdown_toggle",
run: "click",
},
{
trigger: '.o-dropdown-item input[name="livechat_conversation_tag_ids"]',
run: "click",
},
{
trigger: ".o_optional_columns_dropdown_toggle",
run: "click",
},
{
trigger: ".o_list_table:has(.o_data_row:contains(bob_looking_for_help))",
},
{
trigger: '.o_data_cell[name="livechat_conversation_tag_ids"]:not(:has(.o_tag))',
async run() {
const { orm } = odoo.__WOWL_DEBUG__.root.env.services;
[bobChatId] = await orm.search("discuss.channel", [
["livechat_status", "=", "need_help"],
["livechat_agent_partner_ids.name", "like", "bob_looking_for_help%"],
]);
[tagId] = await orm.create("im_livechat.conversation.tag", [{ name: "Discuss" }]);
// Simulate other user adding a tag
await rpc("/im_livechat/conversation/update_tags", {
channel_id: bobChatId,
tag_ids: [tagId],
method: "ADD",
});
},
},
{
trigger:
'.o_data_cell[name="livechat_conversation_tag_ids"]:has(.o_tag:contains(Discuss))',
async run() {
// Simulate other user removing a tag
await rpc("/im_livechat/conversation/update_tags", {
channel_id: bobChatId,
tag_ids: [tagId],
method: "DELETE",
});
},
},
{ trigger: '.o_data_cell[name="livechat_conversation_tag_ids"]:not(:has(.o_tag))' },
],
});

View file

@ -0,0 +1,37 @@
import { registry } from "@web/core/registry";
function makePivotRedirectTourSteps(singleRecordName, multiRecordName) {
return [
{
content: "Click on a cell with a single related record",
trigger: `.o_pivot table tbody tr:has(th:contains(${singleRecordName})) td:eq(0)`,
run: "click",
},
{
trigger: ".o-mail-Discuss",
content: "Verify redirection to the single record view",
},
{
content: "Go back to the pivot view",
trigger: ".o_back_button",
run: "click",
},
{
content: "Click on a cell with a multiple related records",
trigger: `.o_pivot table tbody tr:has(th:contains(${multiRecordName})) td:eq(0)`,
run: "click",
},
{
trigger: ".o_list_view",
content: "Verify redirection to the list view for multiple records",
},
];
}
registry.category("web_tour.tours").add("im_livechat_agents_report_pivot_redirect_tour", {
steps: () => makePivotRedirectTourSteps("test 1", "test 2"),
});
registry.category("web_tour.tours").add("im_livechat_sessions_report_pivot_redirect_tour", {
steps: () => makePivotRedirectTourSteps("operator_1", "operator_2"),
});

View file

@ -0,0 +1,62 @@
import { whenReady } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { patchWithCleanup } from "@web/../tests/helpers/utils";
let firstChannelId;
registry.category("web_tour.tours").add("im_livechat_session_history_open", {
steps: () => [
{
trigger: "body",
async run() {
await whenReady();
const busService = odoo.__WOWL_DEBUG__.root.env.services.bus_service;
patchWithCleanup(busService, {
addChannel(channel) {
document.body.classList.add(`o-bus-channel-${channel}`);
return super.addChannel(...arguments);
},
deleteChannel(channel) {
document.body.classList.remove(`o-bus-channel-${channel}`);
return super.deleteChannel(...arguments);
},
});
},
},
{
trigger: ".o_switch_view[data-tooltip='List']",
run: "click",
},
{
trigger: ".o_data_cell:contains('test 2')",
run: "click",
},
{
trigger: ".o-mail-Message-content:contains('Test Channel 2 Msg')",
async run({ waitFor }) {
firstChannelId =
odoo.__WOWL_DEBUG__.root.env.services.action.currentController.state.resId;
await waitFor(`body.o-bus-channel-discuss\\.channel_${firstChannelId}`, {
timeout: 3000,
});
},
},
{
trigger: ".oi-chevron-right",
run: "click",
},
{
trigger: ".o-mail-Message-content:contains('Test Channel 1 Msg')",
async run({ waitFor }) {
await waitFor(`body:not(.o-bus-channel-discuss\\.channel_${firstChannelId})`, {
timeout: 3000,
});
const channelId =
odoo.__WOWL_DEBUG__.root.env.services.action.currentController.state.resId;
await waitFor(`body.o-bus-channel-discuss\\.channel_${channelId}`, {
trimeout: 3000,
});
},
},
],
});

View file

@ -0,0 +1,38 @@
import { registry } from "@web/core/registry";
registry.category("web_tour.tours").add("im_livechat.looking_for_help_discuss_category_tour", {
steps: () => [
{
// Two live chats are looking for help, they are both in the "Looking for help" category.
trigger:
".o-mail-DiscussSidebarCategory-livechatNeedHelp + .o-mail-DiscussSidebarChannel-container:contains(Visitor Accounting) + .o-mail-DiscussSidebarChannel-container:contains(Visitor Sales)",
},
{
trigger: ".o-mail-DiscussSidebarChannel:contains(Sales) .o-mail-starred",
},
{
trigger:
".o-mail-DiscussSidebarChannel:contains(Accounting):not(:has(.o-mail-starred))",
},
{
trigger: ".o-mail-DiscussSidebarChannel:contains(Accounting)",
run: "hover && click [title='Chat Actions']",
},
{
trigger:
".o-mail-DiscussSidebar:has(.o-mail-DiscussSidebarChannel:contains(Accounting))",
},
{
trigger: "button[name='livechat-status']",
run: "hover",
},
{
trigger: ".o-livechat-LivechatStatusSelection-Label:contains(In progress)",
run: "click",
},
{
trigger:
".o-mail-DiscussSidebar:not(:has(.o-mail-DiscussSidebarChannel:contains(Accounting)))",
},
],
});

View file

@ -0,0 +1,16 @@
import { registry } from "@web/core/registry";
registry.category("web_tour.tours").add("im_livechat.basic_tour", {
steps: () => [
{
trigger: ".channel_name:contains(Support Channel)",
},
{
trigger: ".o-livechat-root:shadow .o-livechat-LivechatButton",
run: "click",
},
{
trigger: ".o-livechat-root:shadow .o-mail-ChatWindow",
},
],
});

View file

@ -0,0 +1,44 @@
import { registry } from "@web/core/registry";
registry.category("web_tour.tours").add("im_livechat.meeting_view_tour", {
steps: () => [
{
trigger: ".o-livechat-root:shadow .o-livechat-LivechatButton",
run: "click",
},
{
trigger: ".o-livechat-root:shadow .o-mail-Thread[data-transient]",
},
{
trigger: ".o-livechat-root:shadow .o-mail-Composer-input",
run: "edit Hello!",
},
{
trigger: ".o-livechat-root:shadow .o-mail-Composer-input",
run: "press Enter",
},
{
trigger: ".o-livechat-root:shadow [title='Join Call']",
run: "click",
},
{
trigger: ".o-livechat-root:shadow .o-discuss-Call [title='Fullscreen']",
run: "click",
},
{
trigger: ".o-livechat-root:shadow .o-mail-Meeting",
},
{
trigger: ".o-livechat-root:shadow .o-mail-MeetingSideActions [name^='more-action:'] ",
run: "click",
},
{
trigger: ".o-livechat-root:shadow [name='call-settings']",
run: "click",
},
{
trigger:
".o-livechat-root:shadow .o-mail-DiscussContent-panelContainer .o-mail-ActionPanel-header:contains('voice settings')",
},
],
});