/** @odoo-module **/ import { registry } from "@web/core/registry"; import { createWebClient } from "./helpers"; import { getFixture, makeDeferred, nextTick, patchDate, patchWithCleanup, } from "@web/../tests/helpers/utils"; import { browser } from "@web/core/browser/browser"; import { ListRenderer } from "@web/views/list/list_renderer"; import { onWillStart, onWillUpdateProps } from "@odoo/owl"; import { errorService } from "@web/core/errors/error_service"; import { makeServerError } from "@web/../tests/helpers/mock_server"; let serverData; let clickEverywhereDef; QUnit.module("clickbot", (hooks) => { hooks.beforeEach(async function () { serverData = { models: { foo: { fields: { foo: { string: "Foo", type: "char" }, bar: { string: "Bar", type: "boolean" }, date: { string: "Some Date", type: "date" }, }, records: [ { id: 1, bar: true, foo: "yop", date: "2017-01-25", }, { id: 2, bar: true, foo: "blip", }, { id: 3, bar: true, foo: "gnap", }, { id: 4, bar: false, foo: "blip", }, ], }, }, views: { "foo,false,search": ` `, "foo,false,list": ` `, "foo,false,kanban": `
`, }, actions: { 1001: { id: 1001, name: "App1", res_model: "foo", type: "ir.actions.act_window", views: [ [false, "list"], [false, "kanban"], ], xml_id: "app1", }, 1002: { id: 1002, name: "App2 Menu 1", res_model: "foo", type: "ir.actions.act_window", views: [[false, "kanban"]], xml_id: "app2_menu1", }, 1022: { id: 1022, name: "App2 Menu 2", res_model: "foo", type: "ir.actions.act_window", views: [[false, "list"]], xml_id: "app2_menu2", }, }, menus: { root: { id: "root", children: [1, 2], name: "root", appID: "root" }, 1: { id: 1, children: [], name: "App1", appID: 1, actionID: 1001, xmlid: "app1" }, 2: { id: 2, children: [3, 4], name: "App2", appID: 2, actionID: 1002, xmlid: "app2", }, 3: { id: 3, children: [], name: "menu 1", appID: 2, actionID: 1002, xmlid: "app2_menu1", }, 4: { id: 4, children: [], name: "menu 2", appID: 2, actionID: 1022, xmlid: "app2_menu2", }, }, }; registry.category("command_categories").add("view_switcher", {}); }); QUnit.test("clickbot clickeverywhere test", async (assert) => { patchDate(2017, 9, 8, 15, 35, 11); // October 8 2017, 15:35:11 patchWithCleanup(browser, { console: { log: (msg) => { assert.step(msg); if (msg === "test successful") { clickEverywhereDef.resolve(); } }, error: (msg) => { assert.step(msg); clickEverywhereDef.resolve(); }, }, }); await createWebClient({ serverData }); clickEverywhereDef = makeDeferred(); window.clickEverywhere(); await clickEverywhereDef; assert.verifySteps([ "Clicking on: apps menu toggle button", "Testing app menu: app1", "Testing menu App1 app1", 'Clicking on: menu item "App1"', "Testing 2 filters", 'Clicking on: filter "Not Bar"', 'Clicking on: filter "Date"', 'Clicking on: filter option "October"', "Testing view switch: kanban", "Clicking on: kanban view switcher", "Testing 2 filters", 'Clicking on: filter "Not Bar"', 'Clicking on: filter "Date"', 'Clicking on: filter option "October"', "Clicking on: apps menu toggle button", "Testing app menu: app2", "Testing menu App2 app2", 'Clicking on: menu item "App2"', "Testing 2 filters", 'Clicking on: filter "Not Bar"', 'Clicking on: filter "Date"', 'Clicking on: filter option "October"', "Testing menu menu 1 app2_menu1", 'Clicking on: menu item "menu 1"', "Testing 2 filters", 'Clicking on: filter "Not Bar"', 'Clicking on: filter "Date"', 'Clicking on: filter option "October"', "Testing menu menu 2 app2_menu2", 'Clicking on: menu item "menu 2"', "Testing 2 filters", 'Clicking on: filter "Not Bar"', 'Clicking on: filter "Date"', 'Clicking on: filter option "October"', "Clicking on: apps menu toggle button", "Successfully tested 2 apps", "Successfully tested 2 menus", "Successfully tested 0 modals", "Successfully tested 10 filters", "test successful", ]); }); QUnit.test("clickbot clickeverywhere test (with dropdown menu)", async (assert) => { serverData.menus.root.children = [2]; serverData.menus[2].children = [5]; serverData.menus[5] = { id: 5, children: [3, 4], name: "a dropdown", appID: 2, xmlid: "app2_dropdown_menu", }; patchDate(2017, 9, 8, 15, 35, 11); // October 8 2017, 15:35:11 patchWithCleanup(browser, { console: { log: (msg) => { assert.step(msg); if (msg === "test successful") { clickEverywhereDef.resolve(); } }, error: (msg) => { assert.step(msg); clickEverywhereDef.resolve(); }, }, }); await createWebClient({ serverData }); await nextTick(); assert.containsOnce( getFixture(), ".o_menu_sections .o-dropdown .dropdown-toggle:contains(a dropdown)" ); clickEverywhereDef = makeDeferred(); window.clickEverywhere(); await clickEverywhereDef; assert.verifySteps([ "Clicking on: apps menu toggle button", "Testing app menu: app2", "Testing menu App2 app2", 'Clicking on: menu item "App2"', "Testing 2 filters", 'Clicking on: filter "Not Bar"', 'Clicking on: filter "Date"', 'Clicking on: filter option "October"', "Clicking on: menu toggler", "Testing menu menu 1 app2_menu1", 'Clicking on: menu item "menu 1"', "Testing 2 filters", 'Clicking on: filter "Not Bar"', 'Clicking on: filter "Date"', 'Clicking on: filter option "October"', "Clicking on: menu toggler", "Testing menu menu 2 app2_menu2", 'Clicking on: menu item "menu 2"', "Testing 2 filters", 'Clicking on: filter "Not Bar"', 'Clicking on: filter "Date"', 'Clicking on: filter option "October"', "Clicking on: apps menu toggle button", "Successfully tested 1 apps", "Successfully tested 2 menus", "Successfully tested 0 modals", "Successfully tested 6 filters", "test successful", ]); }); QUnit.test("clickbot test waiting rpc after clicking filter", async (assert) => { let clickBotStarted = false; serverData.actions = { 1001: { id: 1, name: "App1", res_model: "foo", type: "ir.actions.act_window", views: [[false, "list"]], }, }; serverData.menus = { root: { id: "root", children: [1], name: "root", appID: "root" }, 1: { id: 1, children: [], name: "App1", appID: 1, actionID: 1001, xmlid: "app1" }, }; patchWithCleanup(browser, { console: { log: (msg) => { if (msg === "test successful") { assert.step(msg); clickEverywhereDef.resolve(); } }, error: () => { clickEverywhereDef.resolve(); }, }, }); await createWebClient({ serverData, mockRPC: async function (route, args) { if (args.method === "web_search_read") { if (clickBotStarted) { assert.step("web_search_read called"); await new Promise((r) => setTimeout(r, 1000)); assert.step("response"); } } }, }); clickBotStarted = true; clickEverywhereDef = makeDeferred(); window.clickEverywhere(); await clickEverywhereDef; assert.verifySteps([ "web_search_read called", // click on the App "response", "web_search_read called", // click on the Filter "response", "web_search_read called", // click on the Second Filter "response", "test successful", ]); }); QUnit.test("clickbot show rpc error when an error dialog is detected", async (assert) => { patchDate(2024, 3, 10, 0, 0, 0); let clickBotStarted = false; registry.category("services").add("error", errorService); serverData.actions = { 1001: { id: 1, name: "App1", res_model: "foo", type: "ir.actions.act_window", views: [[false, "list"]], }, }; serverData.menus = { root: { id: "root", children: [1], name: "root", appID: "root" }, 1: { id: 1, children: [], name: "App1", appID: 1, actionID: 1001, xmlid: "app1" }, }; patchWithCleanup(browser, { console: { log: (msg) => { if (msg === "test successful") { assert.step(msg); clickEverywhereDef.resolve(); } }, error: (msg) => { assert.step(msg.toString()); clickEverywhereDef.resolve(); }, }, }); let id = 1; await createWebClient({ serverData, mockRPC: async function (route, args) { if (args.method === "web_search_read") { if (clickBotStarted) { if (id === 3) { // click on the Second Filter throw makeServerError({ message: "This is a server Error, it should be displayed in an error dialog", }); } id++; } } }, }); clickBotStarted = true; clickEverywhereDef = makeDeferred(); window.clickEverywhere(); await clickEverywhereDef; await nextTick(); assert.verifySteps([ 'A RPC in error was detected, maybe it\'s related to the error dialog : {"data":{"id":6,"jsonrpc":"2.0","method":"call","params":{"model":"foo","method":"web_search_read","args":[],"kwargs":{"specification":{"foo":{}},"offset":0,"order":"","limit":80,"context":{"lang":"en","uid":7,"tz":"taht","bin_size":true},"count_limit":10001,"domain":["|",["bar","=",false],"&",["date",">=","2024-04-01"],["date","<=","2024-04-30"]]}}},"settings":{"silent":false},"error":{"name":"RPC_ERROR","type":"server","code":200,"data":{"name":"odoo.exceptions.UserError","debug":"traceback","arguments":[],"context":{}},"exceptionName":"odoo.exceptions.UserError","message":"This is a server Error, it should be displayed in an error dialog","errorEvent":{"isTrusted":true}}}', "Error while testing App1 app1", 'Error: Error dialog detected

An error occurred

Please use the copy button to report the error to your support service.

', ]); }); QUnit.test("clickbot test waiting render after clicking filter", async (assert) => { let clickBotStarted = false; serverData.actions = { 1001: { id: 1, name: "App1", res_model: "foo", type: "ir.actions.act_window", views: [[false, "list"]], }, }; serverData.menus = { root: { id: "root", children: [1], name: "root", appID: "root" }, 1: { id: 1, children: [], name: "App1", appID: 1, actionID: 1001, xmlid: "app1" }, }; patchWithCleanup(browser, { console: { log: (msg) => { if (msg === "test successful") { assert.step(msg); clickEverywhereDef.resolve(); } }, error: () => { clickEverywhereDef.resolve(); }, }, }); patchWithCleanup(ListRenderer.prototype, { setup() { super.setup(...arguments); onWillStart(async () => { if (clickBotStarted) { assert.step("onWillStart called"); await new Promise((r) => setTimeout(r, 1000)); assert.step("response"); } }); onWillUpdateProps(async () => { if (clickBotStarted) { assert.step("onWillUpdateProps called"); await new Promise((r) => setTimeout(r, 1000)); assert.step("response"); } }); }, }); await createWebClient({ serverData }); clickBotStarted = true; clickEverywhereDef = makeDeferred(); window.clickEverywhere(); await clickEverywhereDef; assert.verifySteps([ "onWillStart called", // click on APP "response", "onWillUpdateProps called", // click on filter "response", "onWillUpdateProps called", // click on second filter "response", "test successful", ]); }); QUnit.test("clickbot clickeverywhere menu modal", async (assert) => { patchDate(2017, 9, 8, 15, 35, 11); // October 8 2017, 15:35:11 serverData.views["foo,false,form"] = `
`; serverData.actions["1099"] = { id: 1099, name: "Modal", res_model: "foo", type: "ir.actions.act_window", views: [[false, "form"]], view_mode: "form", target: "new", }; serverData.menus = { root: { id: "root", children: [1, 2], name: "root", appID: "root" }, 1: { id: 1, children: [], name: "App1", appID: 1, actionID: 1001, xmlid: "app1" }, 2: { id: 2, children: [], name: "App Modal", appID: 2, actionID: 1099, xmlid: "test.modal", }, }; patchWithCleanup(browser, { console: { log: (msg) => { assert.step(msg); if (msg === "test successful") { clickEverywhereDef.resolve(); } }, error: (msg) => { assert.step(msg); clickEverywhereDef.resolve(); }, }, }); await createWebClient({ serverData }); clickEverywhereDef = makeDeferred(); window.clickEverywhere(); await clickEverywhereDef; assert.verifySteps([ "Clicking on: apps menu toggle button", "Testing app menu: app1", "Testing menu App1 app1", 'Clicking on: menu item "App1"', "Testing 2 filters", 'Clicking on: filter "Not Bar"', 'Clicking on: filter "Date"', 'Clicking on: filter option "October"', "Testing view switch: kanban", "Clicking on: kanban view switcher", "Testing 2 filters", 'Clicking on: filter "Not Bar"', 'Clicking on: filter "Date"', 'Clicking on: filter option "October"', "Clicking on: apps menu toggle button", "Testing app menu: test.modal", "Testing menu App Modal test.modal", 'Clicking on: menu item "App Modal"', "Modal detected: App Modal test.modal", "Clicking on: modal close button", "Clicking on: apps menu toggle button", "Successfully tested 2 apps", "Successfully tested 0 menus", "Successfully tested 1 modals", "Successfully tested 4 filters", "test successful", ]); }); });