/** @odoo-module **/ import { dialogService } from "@web/core/dialog/dialog_service"; import { notificationService } from "@web/core/notifications/notification_service"; import { ormService } from "@web/core/orm_service"; import { popoverService } from "@web/core/popover/popover_service"; import { registry } from "@web/core/registry"; import { viewService } from "@web/views/view_service"; import { actionService } from "@web/webclient/actions/action_service"; import { effectService } from "@web/core/effects/effect_service"; import { hotkeyService } from "@web/core/hotkeys/hotkey_service"; import { menuService } from "@web/webclient/menus/menu_service"; import { WebClient } from "@web/webclient/webclient"; import { registerCleanup } from "../helpers/cleanup"; import { makeTestEnv } from "../helpers/mock_env"; import { fakeTitleService, fakeCompanyService, makeFakeLocalizationService, makeFakeRouterService, makeFakeHTTPService, makeFakeBarcodeService, makeFakeUserService, } from "../helpers/mock_services"; import { getFixture, mount, nextTick } from "../helpers/utils"; import { uiService } from "@web/core/ui/ui_service"; import { commandService } from "@web/core/commands/command_service"; import { CustomFavoriteItem } from "@web/search/custom_favorite_item/custom_favorite_item"; import { overlayService } from "@web/core/overlay/overlay_service"; import { Component, xml } from "@odoo/owl"; import { fieldService } from "@web/core/field_service"; import { nameService } from "@web/core/name_service"; import { datetimePickerService } from "@web/core/datetime/datetimepicker_service"; const actionRegistry = registry.category("actions"); const serviceRegistry = registry.category("services"); const favoriteMenuRegistry = registry.category("favoriteMenu"); /** * Builds the required registries for tests using a WebClient. * We use a default version of each required registry item. * If the registry already contains one of those items, * the existing one is kept (it means it has been added in the test * directly, e.g. to have a custom version of the item). */ export function setupWebClientRegistries() { const favoriveMenuItems = { "custom-favorite-item": { value: { Component: CustomFavoriteItem, groupNumber: 3 }, options: { sequence: 0 }, }, }; for (const [key, { value, options }] of Object.entries(favoriveMenuItems)) { if (!favoriteMenuRegistry.contains(key)) { favoriteMenuRegistry.add(key, value, options); } } const services = { action: () => actionService, barcode: () => makeFakeBarcodeService(), command: () => commandService, dialog: () => dialogService, effect: () => effectService, field: () => fieldService, hotkey: () => hotkeyService, http: () => makeFakeHTTPService(), localization: () => makeFakeLocalizationService(), menu: () => menuService, name: () => nameService, notification: () => notificationService, orm: () => ormService, overlay: () => overlayService, popover: () => popoverService, router: () => makeFakeRouterService(), title: () => fakeTitleService, ui: () => uiService, user: () => makeFakeUserService(), view: () => viewService, company: () => fakeCompanyService, datetime_picker: () => datetimePickerService, }; for (const serviceName in services) { if (!serviceRegistry.contains(serviceName)) { serviceRegistry.add(serviceName, services[serviceName]()); } } } /** * This method create a web client instance properly configured. * * Note that the returned web client will be automatically cleaned up after the * end of the test. * * @param {*} params */ export async function createWebClient(params) { setupWebClientRegistries(); params.serverData = params.serverData || {}; const mockRPC = params.mockRPC || undefined; const env = await makeTestEnv({ serverData: params.serverData, mockRPC, }); const WebClientClass = params.WebClientClass || WebClient; const target = params && params.target ? params.target : getFixture(); const wc = await mount(WebClientClass, target, { env }); odoo.__WOWL_DEBUG__ = { root: wc }; target.classList.add("o_web_client"); // necessary for the stylesheet registerCleanup(() => { target.classList.remove("o_web_client"); }); // Wait for visual changes caused by a potential loadState await nextTick(); return wc; } export function doAction(env, ...args) { if (env instanceof Component) { env = env.env; } return env.services.action.doAction(...args); } export async function loadState(env, state) { if (env instanceof Component) { env = env.env; } env.bus.trigger("test:hashchange", state); // wait the asynchronous hashchange // (the event hashchange must be triggered in a nonBlocking stack) await nextTick(); // wait for BlankComponent await nextTick(); // wait for the regular rendering await nextTick(); } export function getActionManagerServerData() { // additional basic client action class TestClientAction extends Component {} TestClientAction.template = xml`