diff --git a/addons/account/static/tests/tours/account_dashboard_setup_bar_tests.js b/addons/account/static/tests/tours/account_dashboard_setup_bar_tests.js index a212e1761ef..0d11b027163 100644 --- a/addons/account/static/tests/tours/account_dashboard_setup_bar_tests.js +++ b/addons/account/static/tests/tours/account_dashboard_setup_bar_tests.js @@ -20,7 +20,7 @@ odoo.define('account.dashboard.setup.tour', function (require) { }, { trigger: '.o_control_panel button:contains("' + _t('Print') + '")', }, { - trigger: '.o_control_panel div.o_dropdown_menu a:contains("' + _t('Invoices without Payment') + '")', + trigger: '.o_control_panel .o_dropdown_menu a:contains("' + _t('Invoices without Payment') + '")', }, { trigger: 'iframe .o_report_layout_standard h2', content: 'Primary color is correct', diff --git a/addons/board/static/tests/dashboard_tests.js b/addons/board/static/tests/dashboard_tests.js index 41cc5928c6a..f192f743997 100644 --- a/addons/board/static/tests/dashboard_tests.js +++ b/addons/board/static/tests/dashboard_tests.js @@ -8,6 +8,7 @@ var testUtils = require('web.test_utils'); var ListRenderer = require('web.ListRenderer'); var pyUtils = require('web.py_utils'); +const cpHelpers = testUtils.controlPanel; var createActionManager = testUtils.createActionManager; var createView = testUtils.createView; @@ -701,7 +702,7 @@ QUnit.test('save actions to dashboard', async function (assert) { var result = this._super.apply(this, arguments); result.context = { 'fire': 'on the bayou', - } + }; return result; } }); @@ -733,7 +734,7 @@ QUnit.test('save actions to dashboard', async function (assert) { return Promise.resolve(true); } return this._super.apply(this, arguments); - }, + } }); await actionManager.doAction({ @@ -750,15 +751,16 @@ QUnit.test('save actions to dashboard', async function (assert) { await testUtils.dom.click($('.o_column_sortable')); // Group It - await testUtils.dom.click($('.o_search_options .o_dropdown button:contains(Group By)')); - await testUtils.dom.click($('.o_search_options .o_group_by_menu button')); - await testUtils.dom.click($('.o_search_options .o_group_by_menu button.o_apply_group')); + await cpHelpers.toggleGroupByMenu(actionManager); + await cpHelpers.toggleAddCustomGroup(actionManager); + await cpHelpers.applyGroup(actionManager); // add this action to dashboard - await testUtils.dom.click($('.o_search_options .o_dropdown button:contains(Favorites)')); - await testUtils.dom.click($('.o_add_to_board.o_menu_header')); - testUtils.fields.editInput($('input.o_add_to_board_input'), 'a name'); - await testUtils.dom.click($('.o_add_to_board_confirm_button')); + await cpHelpers.toggleFavoriteMenu(actionManager); + + await testUtils.dom.click($('.o_add_to_board > button')); + await testUtils.fields.editInput($('.o_add_to_board input'), 'a name'); + await testUtils.dom.click($('.o_add_to_board div button')); testUtils.unpatch(ListController); @@ -802,38 +804,28 @@ QUnit.test('save two searches to dashboard', async function (assert) { var filter_count = 0; // Add a first filter - await testUtils.dom.click(actionManager.$('.o_filters_menu_button')); - await testUtils.dom.click(actionManager.$('.o_add_custom_filter')); - actionManager.$('.o_searchview_extended_prop_value .o_input').val('a'); - await testUtils.dom.click(actionManager.$('.o_apply_filter')); + await cpHelpers.toggleFilterMenu(actionManager); + await cpHelpers.toggleAddCustomFilter(actionManager); + await testUtils.fields.editInput(actionManager.el.querySelector('.o_generator_menu_value .o_input'), 'a'); + await cpHelpers.applyFilter(actionManager); + // Add it to dashboard - await testUtils.dom.click(actionManager.$('.o_favorites_menu_button')); - $('.o_search_options .dropdown-menu.o_favorites_menu').one('click', function (ev) { - // This handler is on the webClient - // But since the test suite doesn't have one - // We manually set it here - ev.stopPropagation(); - }); - await testUtils.dom.click(actionManager.$('.o_add_to_board')); - await testUtils.dom.click(actionManager.$('.o_add_to_board_confirm_button')); + await cpHelpers.toggleFavoriteMenu(actionManager); + await testUtils.dom.click($('.o_add_to_board > button')); + await testUtils.dom.click($('.o_add_to_board div button')); + // Remove it - await testUtils.dom.click(actionManager.$('.o_facet_remove')); + await testUtils.dom.click(actionManager.el.querySelector('.o_facet_remove')); // Add the second filter - await testUtils.dom.click(actionManager.$('.o_filters_menu_button')); - await testUtils.dom.click(actionManager.$('.o_add_custom_filter')); - actionManager.$('.o_searchview_extended_prop_value .o_input').val('b'); - await testUtils.dom.click(actionManager.$('.o_apply_filter')); + await cpHelpers.toggleFilterMenu(actionManager); + await cpHelpers.toggleAddCustomFilter(actionManager); + await testUtils.fields.editInput(actionManager.el.querySelector('.o_generator_menu_value .o_input'), "b"); + await cpHelpers.applyFilter(actionManager); // Add it to dashboard - await testUtils.dom.click(actionManager.$('.o_favorites_menu_button')); - $('.o_search_options .dropdown-menu.o_favorites_menu').one('click', function (ev) { - // This handler is on the webClient - // But since the test suite doesn't have one - // We manually set it here - ev.stopPropagation(); - }); - await testUtils.dom.click(actionManager.$('.o_add_to_board')); - await testUtils.dom.click(actionManager.$('.o_add_to_board_confirm_button')); + await cpHelpers.toggleFavoriteMenu(actionManager); + await testUtils.dom.click(actionManager.el.querySelector('.o_add_to_board > button')); + await testUtils.dom.click(actionManager.el.querySelector('.o_add_to_board div button')); actionManager.destroy(); }); @@ -846,7 +838,7 @@ QUnit.test('save a action domain to dashboard', async function (assert) { var filter_domain = ["display_name", "ilike", "b"]; // The filter domain already contains the view domain, but is always added by dashboard.., - var expected_domain = ['&', '&', view_domain, view_domain, filter_domain] + var expected_domain = ['&', '&', view_domain, view_domain, filter_domain]; var actionManager = await createActionManager({ data: this.data, @@ -873,14 +865,18 @@ QUnit.test('save a action domain to dashboard', async function (assert) { }); // Add a filter - await testUtils.dom.click(actionManager.$('.o_filters_menu_button')); - await testUtils.dom.click(actionManager.$('.o_add_custom_filter')); - actionManager.$('.o_searchview_extended_prop_value .o_input').val('b'); - await testUtils.dom.click(actionManager.$('.o_apply_filter')); + await cpHelpers.toggleFilterMenu(actionManager); + await cpHelpers.toggleAddCustomFilter(actionManager); + await testUtils.fields.editInput( + actionManager.el.querySelector('.o_generator_menu_value .o_input'), + "b" + ); + await cpHelpers.applyFilter(actionManager); // Add it to dashboard - await testUtils.dom.click(actionManager.$('.o_favorites_menu_button')); - await testUtils.dom.click(actionManager.$('.o_add_to_board')); - await testUtils.dom.click(actionManager.$('.o_add_to_board_confirm_button')); + await cpHelpers.toggleFavoriteMenu(actionManager); + await testUtils.dom.click(actionManager.el.querySelector('.o_add_to_board > button')); + // add + await testUtils.dom.click(actionManager.el.querySelector('.o_add_to_board div button')); actionManager.destroy(); }); diff --git a/addons/google_drive/static/tests/gdrive_test.js b/addons/google_drive/static/tests/gdrive_test.js index 158330376bd..b04ebf27c26 100644 --- a/addons/google_drive/static/tests/gdrive_test.js +++ b/addons/google_drive/static/tests/gdrive_test.js @@ -1,166 +1,129 @@ odoo.define('google_drive.gdrive_integration', function (require) { -"use strict"; -//rebuild -var FormView = require('web.FormView'); -var testUtils = require('web.test_utils'); -var GoogleDriveSideBar = require('google_drive.sidebar'); + "use strict"; -var createView = testUtils.createView; + const FormView = require('web.FormView'); + const testUtils = require('web.test_utils'); -/* - * @override - * Avoid breaking other tests because of the new route - * that the module introduces - */ -var _addGoogleDocItemsOriginal = GoogleDriveSideBar.prototype._addGoogleDocItems; + const cpHelpers = testUtils.controlPanel; -var _addGoogleDocItemsMocked = function (model, resID) { - return Promise.resolve(); -}; - -GoogleDriveSideBar.prototype._addGoogleDocItems = _addGoogleDocItemsMocked; - -QUnit.module('gdrive_integration', { - beforeEach: function () { - // For our test to work, the _addGoogleDocItems function needs to be the original - GoogleDriveSideBar.prototype._addGoogleDocItems = _addGoogleDocItemsOriginal; - - this.data = { - partner: { - fields: { - display_name: {string: "Displayed name", type: "char", searchable: true}, + QUnit.module('Google Drive Integration', { + beforeEach() { + this.data = { + partner: { + fields: { + display_name: { string: "Displayed name", type: "char", searchable: true }, + }, + records: [ + { id: 1, display_name: "Locomotive Breath" }, + { id: 2, display_name: "Hey Macarena" }, + ], }, - records: [{ - id: 1, - display_name: "Locomotive Breath", - }, { - id: 2, - display_name: "Hey Macarena", - }], - }, - 'google.drive.config': { - fields: { - model_id: {string: 'Model', type: 'int'}, - name: {string: 'Name', type: 'char'}, - google_drive_resource_id: {string: 'Resource ID', type: 'char'}, + }; + }, + }, function () { + + QUnit.module('Google Drive ActionMenus'); + + QUnit.test('rendering of the google drive attachments in action menus', async function (assert) { + assert.expect(3); + + const form = await testUtils.createView({ + actionMenusRegistry: true, + arch: + `
+ + `, + data: this.data, + async mockRPC(route, args) { + switch (route) { + case '/web/dataset/call_kw/google.drive.config/get_google_drive_config': + assert.deepEqual(args.args, ['partner', 1], + 'The route to get google drive config should have been called'); + return [{ + id: 27, + name: 'Cyberdyne Systems', + }]; + case '/web/dataset/call_kw/google.drive.config/search_read': + return [{ + google_drive_resource_id: "T1000", + google_drive_client_id: "cyberdyne.org", + id: 1, + }]; + case '/web/dataset/call_kw/google.drive.config/get_google_drive_url': + assert.deepEqual(args.args, [27, 1, 'T1000'], + 'The route to get the Google url should have been called'); + return; // do not return anything or it will open a new tab. + } }, - records: [{ - id: 27, - name: 'Cyberdyne Systems', - model_id: 1, - google_drive_resource_id: 'T1000', - }], - }, - 'ir.attachment': { - fields: { - name: {string: 'Name', type:'char'} + model: 'partner', + res_id: 1, + View: FormView, + viewOptions: { + hasActionMenus: true, }, - records: [], - } - }; - }, + }); + await cpHelpers.toggleActionMenu(form); - afterEach: function() { - GoogleDriveSideBar.prototype._addGoogleDocItems = _addGoogleDocItemsMocked; - } + assert.containsOnce(form, '.oe_share_gdoc_item', + "The button to the google action should be present"); -}, function () { - QUnit.module('Google Drive Sidebar'); + await cpHelpers.toggleMenuItem(form, "Cyberdyne Systems"); - QUnit.test('rendering of the google drive attachments in Sidebar', async function (assert) { - assert.expect(3); - - var form = await createView({ - View: FormView, - model: 'partner', - data: this.data, - arch: '
' + - '' + - '', - res_id: 1, - viewOptions: {hasSidebar: true}, - mockRPC: function (route, args) { - if (route === '/web/dataset/call_kw/google.drive.config/get_google_drive_config') { - assert.deepEqual(args.args, ['partner', 1], - 'The route to get google drive config should have been called'); - return Promise.resolve([{id: 27, name: 'Cyberdyne Systems'}]); - } - if (route === '/web/dataset/call_kw/google.drive.config/search_read'){ - return Promise.resolve([{google_drive_resource_id: "T1000", - google_drive_client_id: "cyberdyne.org", - id: 1}]); - } - if (route === '/web/dataset/call_kw/google.drive.config/get_google_drive_url') { - assert.deepEqual(args.args, [27, 1, 'T1000'], - 'The route to get the Google url should have been called'); - // We don't return anything useful, otherwise it will open a new tab - return Promise.resolve(); - } - return this._super.apply(this, arguments); - }, + form.destroy(); }); - var $googleAction = form.sidebar.$('.oe_share_gdoc'); + QUnit.test('click on the google drive attachments after switching records', async function (assert) { + assert.expect(4); - assert.strictEqual($googleAction.length, 1, - 'The button to the google action should be present'); + let currentID; + const form = await testUtils.createView({ + actionMenusRegistry: true, + arch: + `
+ + `, + data: this.data, + async mockRPC(route, args) { + switch (route) { + case '/web/dataset/call_kw/google.drive.config/get_google_drive_config': + assert.deepEqual(args.args, ['partner', currentID], + 'The route to get google drive config should have been called'); + return [{ + id: 27, + name: 'Cyberdyne Systems', + }]; + case '/web/dataset/call_kw/google.drive.config/search_read': + return [{ + google_drive_resource_id: "T1000", + google_drive_client_id: "cyberdyne.org", + id: 1, + }]; + case '/web/dataset/call_kw/google.drive.config/get_google_drive_url': + assert.deepEqual(args.args, [27, currentID, 'T1000'], + 'The route to get the Google url should have been called'); + return; // do not return anything or it will open a new tab. + } + }, + model: 'partner', + res_id: 1, + View: FormView, + viewOptions: { + hasActionMenus: true, + ids: [1, 2], + index: 0, + }, + }); + currentID = 1; + await cpHelpers.toggleActionMenu(form); + await cpHelpers.toggleMenuItem(form, "Cyberdyne Systems"); - // click on gdrive sidebar item - await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)')); - await testUtils.dom.click($googleAction); + await cpHelpers.pagerNext(form); - form.destroy(); - }); + currentID = 2; + await cpHelpers.toggleActionMenu(form); + await cpHelpers.toggleMenuItem(form, "Cyberdyne Systems"); - QUnit.test('click on the google drive attachments after switching records', async function (assert) { - assert.expect(3); - - var currentID; - var form = await createView({ - View: FormView, - model: 'partner', - data: this.data, - arch: '
' + - '' + - '', - res_id: 1, - viewOptions: { - hasSidebar: true, - ids: [1, 2], - index: 0, - }, - mockRPC: function (route, args) { - if (route === '/web/dataset/call_kw/google.drive.config/get_google_drive_config') { - assert.deepEqual(args.args, ['partner', 1], - 'The route to get google drive config should have been called'); - return Promise.resolve([{id: 27, name: 'Cyberdyne Systems'}]); - } - if (route === '/web/dataset/call_kw/google.drive.config/search_read'){ - return Promise.resolve([{google_drive_resource_id: "T1000", - google_drive_client_id: "cyberdyne.org", - id: 1}]); - } - if (route === '/web/dataset/call_kw/google.drive.config/get_google_drive_url') { - assert.deepEqual(args.args, [27, currentID, 'T1000'], - 'The route to get the Google url should have been called'); - // We don't return anything useful, otherwise it will open a new tab - return Promise.resolve(); - } - return this._super.apply(this, arguments); - }, + form.destroy(); }); - - currentID = 1; - await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)')); - await testUtils.dom.click(form.sidebar.$('.oe_share_gdoc')); - - await testUtils.dom.click(form.pager.$('.o_pager_next')); - currentID = 2; - await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)')); - await testUtils.dom.click(form.sidebar.$('.oe_share_gdoc')); - - form.destroy(); }); }); - -}); diff --git a/addons/im_support/static/tests/systray_no_support_tests.js b/addons/im_support/static/tests/systray_no_support_tests.js index 80e3d443597..c56e371bc0e 100644 --- a/addons/im_support/static/tests/systray_no_support_tests.js +++ b/addons/im_support/static/tests/systray_no_support_tests.js @@ -38,7 +38,7 @@ QUnit.test('messaging menu does not display the Support channel if not available assert.expect(1); var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { data: this.data, services: this.services, }); diff --git a/addons/im_support/static/tests/systray_tests.js b/addons/im_support/static/tests/systray_tests.js index 9df4c3b2bd8..75358276bc3 100644 --- a/addons/im_support/static/tests/systray_tests.js +++ b/addons/im_support/static/tests/systray_tests.js @@ -33,7 +33,7 @@ QUnit.test('messaging menu displays the Support channel', async function (assert assert.expect(1); var messagingMenu = new MessagingMenu(); - addMockSupportEnvironment(messagingMenu, { + await addMockSupportEnvironment(messagingMenu, { data: this.data, services: this.services, session: this.supportParams, @@ -51,7 +51,7 @@ QUnit.test('clicking on Support channel: channel not available', async function assert.expect(9); var messagingMenu = new MessagingMenu(); - addMockSupportEnvironment(messagingMenu, { + await addMockSupportEnvironment(messagingMenu, { data: this.data, mockRPC: function (route, args) { if (!_.string.endsWith(route, '.png')) { // ignore images @@ -100,7 +100,7 @@ QUnit.test('clicking on Support channel: channel available', async function (ass assert.expect(9); var messagingMenu = new MessagingMenu(); - addMockSupportEnvironment(messagingMenu, { + await addMockSupportEnvironment(messagingMenu, { data: this.data, mockRPC: function (route, args) { if (!_.string.endsWith(route, '.png')) { // ignore images @@ -145,7 +145,7 @@ QUnit.test('post messages in Support channel', async function (assert) { assert.expect(8); var messagingMenu = new MessagingMenu(); - addMockSupportEnvironment(messagingMenu, { + await addMockSupportEnvironment(messagingMenu, { data: this.data, mockRPC: function (route, args) { if (!_.string.endsWith(route, '.png')) { // ignore images @@ -190,7 +190,7 @@ QUnit.test('fold Support channel', async function (assert) { assert.expect(11); var messagingMenu = new MessagingMenu(); - addMockSupportEnvironment(messagingMenu, { + await addMockSupportEnvironment(messagingMenu, { data: this.data, mockRPC: function (route, args) { if (!_.string.endsWith(route, '.png')) { // ignore images @@ -245,7 +245,7 @@ QUnit.test('restore Support channel if necessary', async function (assert) { assert.expect(5); var messagingMenu = new MessagingMenu(); - addMockSupportEnvironment(messagingMenu, { + await addMockSupportEnvironment(messagingMenu, { data: this.data, enableSupportPoll: true, mockRPC: function (route, args) { @@ -270,8 +270,8 @@ QUnit.test('restore Support channel if necessary', async function (assert) { "should have open a chat window"); assert.verifySteps([ - 'cors: /odoo_im_support/get_support_channel', '/mail/init_messaging', + 'cors: /odoo_im_support/get_support_channel', 'cors: /odoo_im_support/fetch_messages', ]); @@ -284,7 +284,7 @@ QUnit.test('receive messages in the Support channel', async function (assert) { var supportChannelID; var messagingMenu = new MessagingMenu(); - addMockSupportEnvironment(messagingMenu, { + await addMockSupportEnvironment(messagingMenu, { data: this.data, enableSupportPoll: true, mockRPC: function (route, args) { @@ -330,8 +330,8 @@ QUnit.test('receive messages in the Support channel', async function (assert) { 'A message', "message is correct"); assert.verifySteps([ - 'cors: /odoo_im_support/get_support_channel', '/mail/init_messaging', + 'cors: /odoo_im_support/get_support_channel', 'cors: /odoo_im_support/fetch_messages', ]); diff --git a/addons/mail/static/tests/activity_tests.js b/addons/mail/static/tests/activity_tests.js index c32702d8c45..570bf2165af 100644 --- a/addons/mail/static/tests/activity_tests.js +++ b/addons/mail/static/tests/activity_tests.js @@ -316,7 +316,6 @@ QUnit.test('activity view: activity widget', async function (assert) { }, }; - owl.Component.env = testUtils.mock.getMockedOwlEnv(params); var activity = await createView(params); var today = activity.$('table tbody tr:first td:nth-child(2).today'); var dropdown = today.find('.dropdown-menu.o_activity'); @@ -391,9 +390,9 @@ QUnit.test('activity view: no group_by_menu and no time_range_menu', async funct assert.containsN(actionManager, '.o_search_options .o_dropdown button:visible', 2, "only two elements should be available in view search"); - assert.isVisible(actionManager.$('.o_search_options .o_dropdown button.o_filters_menu_button'), + assert.isVisible(actionManager.$('.o_search_options .o_dropdown.o_filter_menu > button'), "filter should be available in view search"); - assert.isVisible(actionManager.$('.o_search_options .o_dropdown button.o_favorites_menu_button'), + assert.isVisible(actionManager.$('.o_search_options .o_dropdown.o_favorite_menu > button'), "favorites should be available in view search"); actionManager.destroy(); }); diff --git a/addons/mail/static/tests/discuss_tests.js b/addons/mail/static/tests/discuss_tests.js index b12b4b1d9b3..8cf73248754 100644 --- a/addons/mail/static/tests/discuss_tests.js +++ b/addons/mail/static/tests/discuss_tests.js @@ -7,6 +7,7 @@ var mailTestUtils = require('mail.testUtils'); var testUtils = require('web.test_utils'); var createDiscuss = mailTestUtils.createDiscuss; +const cpHelpers = testUtils.controlPanel; QUnit.module('mail', {}, function () { QUnit.module('Discuss', { @@ -139,6 +140,7 @@ QUnit.test('basic rendering', async function (assert) { var $history = $sidebar.find('.o_mail_discuss_item[data-thread-id=mailbox_history]'); assert.strictEqual($history.length, 1, "should have the mailbox item 'mailbox_history' in the sidebar"); + discuss.destroy(); }); @@ -305,43 +307,44 @@ QUnit.test('searchview filter messages', async function (assert) { '', }, }); - assert.containsN(discuss, '.o_thread_message', 2, - "there should be two messages in the inbox mailbox"); - assert.strictEqual($('.o_searchview_input').length, 1, - "there should be a searchview on discuss"); - assert.strictEqual($('.o_searchview_input').val(), '', - "the searchview should be empty initially"); + // needed to handle events triggered by the controlPanelModel + discuss.on_attach_callback(); + await testUtils.nextTick(); - // interact with searchview so that there is only once message - $('.o_searchview_input').val("ab").trigger('keyup'); - await testUtils.nextTick(); - $('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.ENTER })); - await testUtils.nextTick(); - assert.strictEqual($('.o_searchview_facet').length, 1, - "the searchview should have a facet"); - assert.strictEqual($('.o_facet_values').text().trim(), 'ab', - "the facet should be a search on 'ab'"); - assert.containsOnce(discuss, '.o_thread_message', - "there should be a single message after filter"); + assert.containsN(discuss, '.o_thread_message', 2, + "there should be two messages in the inbox mailbox"); + assert.strictEqual($('.o_searchview_input').length, 1, + "there should be a searchview on discuss"); + assert.strictEqual($('.o_searchview_input').val(), '', + "the searchview should be empty initially"); - // interact with search view so that there are no matching messages - await testUtils.dom.click($('.o_facet_remove')); - $('.o_searchview_input').val("abcd").trigger('keyup'); - await testUtils.nextTick(); - $('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.ENTER })); - await testUtils.nextTick(); + // interact with searchview so that there is only once message + await cpHelpers.editSearch(discuss, "ab"); + await cpHelpers.validateSearch(discuss); + assert.strictEqual($('.o_searchview_facet').length, 1, + "the searchview should have a facet"); + assert.strictEqual($('.o_facet_values').text().trim(), 'ab', + "the facet should be a search on 'ab'"); + assert.containsOnce(discuss, '.o_thread_message', + "there should be a single message after filter"); - assert.strictEqual($('.o_searchview_facet').length, 1, - "the searchview should have a facet"); - assert.strictEqual($('.o_facet_values').text().trim(), 'abcd', - "the facet should be a search on 'abcd'"); - assert.containsNone(discuss, '.o_thread_message', - "there should be no message after 2nd filter"); - assert.strictEqual(discuss.$('.o_thread_title').text().trim(), - "No matches found", - "should display that there are no matching messages"); + // interact with search view so that there are no matching messages + await testUtils.dom.click($('.o_facet_remove')); + await cpHelpers.editSearch(discuss, "abcd"); + await cpHelpers.validateSearch(discuss); - discuss.destroy(); + assert.strictEqual($('.o_searchview_facet').length, 1, + "the searchview should have a facet"); + assert.strictEqual($('.o_facet_values').text().trim(), 'abcd', + "the facet should be a search on 'abcd'"); + assert.containsNone(discuss, '.o_thread_message', + "there should be no message after 2nd filter"); + assert.strictEqual(discuss.$('.o_thread_title').text().trim(), + "No matches found", + "should display that there are no matching messages"); + + discuss.on_detach_callback(); + discuss.destroy(); }); @@ -1147,6 +1150,7 @@ QUnit.test('mark all messages as read from Inbox', async function (assert) { await testUtils.dom.click($markAllReadButton); + markAllReadDef.then(function () { // immediately jump to end of the fadeout animation on messages $inbox = discuss.$('.o_mail_discuss_item[data-thread-id="mailbox_inbox"]'); @@ -1964,33 +1968,38 @@ QUnit.test('save filter discuss', async function (assert) { } return this._super.apply(this,arguments); }, - intercepts: { - create_filter: function (ev) { - assert.deepEqual( - JSON.parse(ev.data.filter.domain), [ - "|", - ["subject", "ilike", "she was born in a hurricane"], - ["body", "ilike", "she was born in a hurricane"] - ], 'The filter should have been saved with the right domain'); + env: { + dataManager: { + create_filter: async function (filter) { + assert.deepEqual( + JSON.parse(filter.domain), [ + "|", + ["subject", "ilike", "she was born in a hurricane"], + ["body", "ilike", "she was born in a hurricane"] + ], 'The filter should have been saved with the right domain'); + } } } }); + // needed to handle events triggered by the controlPanelModel + discuss.on_attach_callback(); + await testUtils.nextTick(); assert.containsOnce(discuss, '.o_searchview_input_container', 'search view input present'); - $('.o_searchview_input').val("she was born in a hurricane").trigger('keyup'); - await testUtils.nextTick(); + await cpHelpers.editSearch(discuss, "she was born in a hurricane"); messageFetchCount = 1; - $('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.ENTER })); - await testUtils.nextTick(); - await testUtils.dom.click(discuss.$('.o_favorites_menu_button')); - await testUtils.dom.click(discuss.$('.o_add_favorite')); + await cpHelpers.validateSearch(discuss); - await testUtils.fields.editInput(discuss.$('.o_favorite_name input'), 'War'); - await testUtils.dom.click(discuss.$('.o_save_favorite button')); + await cpHelpers.toggleFavoriteMenu(discuss); + await cpHelpers.toggleSaveFavorite(discuss); + await cpHelpers.editFavoriteName(discuss, "War"); + await cpHelpers.saveFavorite(discuss); + + discuss.on_detach_callback(); discuss.destroy(); }); diff --git a/addons/mail/static/tests/document_thread_window_tests.js b/addons/mail/static/tests/document_thread_window_tests.js index d10f32c1e89..f01ab0925f2 100644 --- a/addons/mail/static/tests/document_thread_window_tests.js +++ b/addons/mail/static/tests/document_thread_window_tests.js @@ -91,7 +91,7 @@ QUnit.test('open a document thread in a thread window', async function (assert) assert.expect(6); var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: this.session, @@ -129,7 +129,7 @@ QUnit.test('expand a document thread window', async function (assert) { assert.expect(4); var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: this.session, @@ -177,7 +177,7 @@ QUnit.test('post messages in a document thread window', async function (assert) res_id: 1, }; var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: this.session, @@ -229,7 +229,7 @@ QUnit.test('post messages in a document thread window', async function (assert) QUnit.test('open, fold, unfold and close a document thread window', async function (assert) { assert.expect(20); var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: this.session, @@ -285,7 +285,7 @@ QUnit.test('do not open thread window on fetch message failure', async function assert.expect(4); var messagingMenu = new MessagingMenu(); - testUtils.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: this.session, diff --git a/addons/mail/static/tests/systray/systray_messaging_menu_mail_failure_tests.js b/addons/mail/static/tests/systray/systray_messaging_menu_mail_failure_tests.js index f2c8e95ac29..3f07f84cbfd 100644 --- a/addons/mail/static/tests/systray/systray_messaging_menu_mail_failure_tests.js +++ b/addons/mail/static/tests/systray/systray_messaging_menu_mail_failure_tests.js @@ -82,7 +82,7 @@ QUnit.test('preview of mail failure', async function (assert) { }]; var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { data: this.data, services: this.services, }); @@ -138,7 +138,7 @@ QUnit.test('preview grouped failures by document', async function (assert) { }]; var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { data: this.data, services: this.services, }); @@ -194,7 +194,7 @@ QUnit.test('preview grouped failures by document model', async function (assert) }]; var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { data: this.data, services: this.services, }); diff --git a/addons/mail/static/tests/systray/systray_messaging_menu_tests.js b/addons/mail/static/tests/systray/systray_messaging_menu_tests.js index 5cca1454b95..f3e2131862c 100644 --- a/addons/mail/static/tests/systray/systray_messaging_menu_tests.js +++ b/addons/mail/static/tests/systray/systray_messaging_menu_tests.js @@ -105,7 +105,7 @@ QUnit.test('messaging menu widget: menu with no records', async function (assert assert.expect(1); var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, mockRPC: function (route, args) { if (args.method === 'message_fetch') { @@ -114,7 +114,7 @@ QUnit.test('messaging menu widget: menu with no records', async function (assert return this._super.apply(this, arguments); } }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); assert.hasClass(messagingMenu.$('.o_no_activity'),'o_no_activity', "should not have instance of widget"); messagingMenu.destroy(); @@ -126,7 +126,7 @@ QUnit.test('messaging menu widget: messaging not ready', async function (assert) const messagingReadyProm = testUtils.makeTestPromise(); const messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, async mockRPC(route, args) { if (route === '/mail/init_messaging') { @@ -142,7 +142,7 @@ QUnit.test('messaging menu widget: messaging not ready', async function (assert) return this._super(...arguments); }, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); assert.verifySteps(['/mail/init_messaging:pending']); assert.ok( messagingMenu.el, @@ -170,11 +170,11 @@ QUnit.test('messaging menu widget: messaging not ready', async function (assert) QUnit.test('messaging menu widget: messaging menu with 1 record', async function (assert) { assert.expect(3); var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); @@ -197,14 +197,14 @@ QUnit.test('messaging menu widget: open inbox for needaction not linked to any d assert.expect(4); var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: { partner_id: 1, }, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); // Simulate received needaction message without associated document, // so that we have a message in inbox without a model and a resID @@ -272,12 +272,12 @@ QUnit.test("messaging menu widget: mark as read on thread preview", async functi }]; var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); assert.hasClass(messagingMenu.$el,'o_mail_systray_item', 'should be the instance of widget'); @@ -335,14 +335,14 @@ QUnit.test('needaction messages in channels should appear, in addition to channe this.data['mail.message'].records = [needactionMessage, lastMessage]; var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: { partner_id: partnerID, }, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); @@ -391,14 +391,15 @@ QUnit.test('preview of message on a document + mark as read', async function (as this.data['mail.message'].records.push(needactionMessage); var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: { partner_id: partnerID, }, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); + await testUtils.nextTick(); assert.strictEqual(messagingMenu.$('.o_notification_counter').text(), '1', "should display a counter of 1 on the messaging menu icon"); @@ -427,11 +428,11 @@ QUnit.test('update messaging preview on receiving a new message in channel previ assert.expect(8); var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); @@ -478,11 +479,11 @@ QUnit.test('new message of type "notification" are not considered as unread mess assert.expect(8); const messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { data: this.data, services: this.services, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); // open messaging menu await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); assert.containsOnce( @@ -580,7 +581,7 @@ QUnit.test('preview of inbox message not linked to document + mark as read', asy this.data['mail.message'].records.concat(needactionMessages); var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: { @@ -593,7 +594,9 @@ QUnit.test('preview of inbox message not linked to document + mark as read', asy return this._super.apply(this, arguments); }, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); + await testUtils.nextTick(); + assert.strictEqual(messagingMenu.$('.o_notification_counter').text(), '2', "should display a counter of 2 on the messaging menu icon"); @@ -673,14 +676,14 @@ QUnit.test('grouped preview for needaction messages linked to same document', as this.data.initMessaging.needaction_inbox_counter = 2; var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: { partner_id: 44, }, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); var $previews = messagingMenu.$('.o_mail_preview'); @@ -719,13 +722,13 @@ QUnit.test("messaging menu widget: channel seen notification", async function (a }; var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: { partner_id: 3 }, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); assert.strictEqual(messagingMenu.$('.o_notification_counter').text(), '1', @@ -767,13 +770,13 @@ QUnit.test("messaging menu widget: no traceback when receiving channel_fetched n }; var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: { partner_id: 3 }, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); assert.containsOnce(messagingMenu, '.o_new_message', "should have button to open blank thread window"); @@ -806,12 +809,12 @@ QUnit.test("messaging menu widget: preview with no message should be undated", a this.data['mail.message'].records[0].channel_ids = []; var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); assert.strictEqual(messagingMenu.$('.o_mail_preview').length, 1, @@ -836,12 +839,12 @@ QUnit.test("messaging menu widget: sort dated previews before undated previews", this.data.initMessaging.channel_slots.direct_message = [dm]; var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); assert.strictEqual(messagingMenu.$('.o_mail_preview').length, 2, @@ -924,16 +927,19 @@ QUnit.test('global counter with channel previews', async function (assert) { this.data['mail.message'].records = messages; var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: { partner_id: 3, }, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); + await testUtils.nextTick(); + assert.strictEqual(messagingMenu.$('.o_notification_counter').text(), '2', "should display a counter of 2 on the messaging menu icon"); + await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); assert.strictEqual(messagingMenu.$('.o_mail_preview').length, 3, @@ -965,7 +971,7 @@ QUnit.test('messaging menu widget: do not open chat window twice on preview clic var messageFetchDef = testUtils.makeTestPromise(); var messagingMenu = new MessagingMenu(); - testUtils.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: { partner_id: 1 }, @@ -991,7 +997,7 @@ QUnit.test('messaging menu widget: do not open chat window twice on preview clic return this._super.apply(this, arguments); }, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); // Opening chat window from messaging menu (pending from `messageFetchDef`) await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); @@ -1023,7 +1029,7 @@ QUnit.test('messaging menu widget: expand on thread preview', async function (as }); var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: { partner_id: 44 }, @@ -1036,7 +1042,7 @@ QUnit.test('messaging menu widget: expand on thread preview', async function (as }, }, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); var $preview = messagingMenu.$('.o_mail_preview'); @@ -1062,7 +1068,7 @@ QUnit.test('messaging menu widget: click twice preview on slow message_fetch sho const messageFetchProm = testUtils.makeTestPromise(); const messagingMenu = new MessagingMenu(); - testUtils.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, session: { partner_id: 1 }, @@ -1086,7 +1092,7 @@ QUnit.test('messaging menu widget: click twice preview on slow message_fetch sho return this._super(...arguments); }, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); // Opening chat window 1st time from messaging menu (pending from `messageFetchDef`) await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); @@ -1113,11 +1119,11 @@ QUnit.test('no code injection in message body preview', async function (assert) `

`; const messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { services: this.services, data: this.data, }); - await messagingMenu.appendTo($('#qunit-fixture')); + await messagingMenu.appendTo(testUtils.prepareTarget()); await testUtils.dom.click(messagingMenu.$('.dropdown-toggle')); assert.containsOnce( messagingMenu, diff --git a/addons/mail_bot/static/tests/systray_messaging_menu_tests.js b/addons/mail_bot/static/tests/systray_messaging_menu_tests.js index e2d4af883bf..2494d639b29 100644 --- a/addons/mail_bot/static/tests/systray_messaging_menu_tests.js +++ b/addons/mail_bot/static/tests/systray_messaging_menu_tests.js @@ -70,7 +70,7 @@ QUnit.test('messaging menu widget: rendering with OdooBot has a request', async assert.expect(5); var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { data: this.data, services: this.services, }); @@ -99,7 +99,7 @@ QUnit.test('messaging menu widget: rendering without OdooBot has a request (deni window.Notification.permission = 'denied'; var messagingMenu = new MessagingMenu(); - testUtils.mock.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { data: this.data, services: this.services, }); @@ -122,7 +122,7 @@ QUnit.test('messaging menu widget: rendering without OdooBot has a request (acce window.Notification.permission = 'granted'; var messagingMenu = new MessagingMenu(); - testUtils.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { data: this.data, services: this.services, }); @@ -143,7 +143,7 @@ QUnit.test('messaging menu widget: respond to notification prompt', async functi assert.expect(4); var messagingMenu = new MessagingMenu(); - testUtils.addMockEnvironment(messagingMenu, { + await testUtils.mock.addMockEnvironment(messagingMenu, { data: this.data, services: this.services, }); diff --git a/addons/web/static/tests/chrome/action_manager_tests.js b/addons/web/static/tests/chrome/action_manager_tests.js index 6af38ce02de..2c987215d43 100644 --- a/addons/web/static/tests/chrome/action_manager_tests.js +++ b/addons/web/static/tests/chrome/action_manager_tests.js @@ -16,7 +16,9 @@ var ReportService = require('web.ReportService'); var SessionStorageService = require('web.SessionStorageService'); var testUtils = require('web.test_utils'); var Widget = require('web.Widget'); + var createActionManager = testUtils.createActionManager; +const cpHelpers = testUtils.controlPanel; QUnit.module('ActionManager', { beforeEach: function () { @@ -198,8 +200,9 @@ QUnit.module('ActionManager', { var n = delta; await actionManager.doAction(4); + // kanban view is loaded, switch to list view - await testUtils.dom.click($('.o_control_panel .o_cp_switch_list')); + await cpHelpers.switchView(actionManager, 'list'); // open a record in form view await testUtils.dom.click(actionManager.$('.o_list_view .o_data_row:first')); // go back to action 7 in breadcrumbs @@ -1336,12 +1339,13 @@ QUnit.module('ActionManager', { }, }); await actionManager.doAction(4); + // kanban view is loaded, switch to list view - await testUtils.dom.click($('.o_control_panel .o_cp_switch_list')); + await cpHelpers.switchView(actionManager, 'list'); // here, list view is not ready yet, because def is not resolved // switch back to kanban view - await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban')); + await cpHelpers.switchView(actionManager, 'kanban'); // here, we want the kanban view to reload itself, regardless of list view assert.verifySteps([ @@ -1607,8 +1611,8 @@ QUnit.module('ActionManager', { 'load_views', // action 3 '/web/dataset/search_read', // search read of list view of action 3 '/web/action/load', // action 4 - 'load_views', // action 4 'read', // read the opened record of action 3 (this request is blocked) + 'load_views', // action 4 '/web/dataset/search_read', // search read action 4 ]); @@ -1753,7 +1757,7 @@ QUnit.module('ActionManager', { // reload (the search_read RPC will be blocked) def = testUtils.makeTestPromise(); await testUtils.nextTick(); - await testUtils.dom.click($('.o_control_panel .o_cp_switch_list')); + await cpHelpers.switchView(actionManager, 'list'); assert.containsN(actionManager, '.o_list_view .o_data_row', 5, "list view should still contain 5 records"); @@ -1822,11 +1826,11 @@ QUnit.module('ActionManager', { var ClientAction = AbstractAction.extend({ hasControlPanel: true, - start: function () { + start: async function () { this.$('.o_content').text('Hello World'); this.$el.addClass('o_client_action_test'); - this._setTitle('Hello'); - return this._super.apply(this, arguments); + this.controlPanelProps.title = 'Hello'; + await this._super.apply(this, arguments); }, }); core.action_registry.add('HelloWorldTest', ClientAction); @@ -1885,14 +1889,14 @@ QUnit.module('ActionManager', { hasControlPanel: true, events: { click: function () { - this._setTitle('new title'); + this.updateControlPanel({ title: 'new title' }); }, }, - start: function () { - this._setTitle('initial title'); + start: async function () { this.$('.o_content').text('Hello World'); this.$el.addClass('o_client_action_test'); - return this._super.apply(this, arguments); + this.controlPanelProps.title = 'initial title'; + await this._super.apply(this, arguments); }, }); var actionManager = await createActionManager(); @@ -1902,7 +1906,7 @@ QUnit.module('ActionManager', { assert.strictEqual($('ol.breadcrumb').text(), "initial title", "should have initial title as breadcrumb content"); - testUtils.dom.click(actionManager.$('.o_client_action_test')); + await testUtils.dom.click(actionManager.$('.o_client_action_test')); assert.strictEqual($('ol.breadcrumb').text(), "new title", "should have updated title as breadcrumb content"); @@ -2322,7 +2326,7 @@ QUnit.module('ActionManager', { }); QUnit.test('sidebar is present in list view', async function (assert) { - assert.expect(5); + assert.expect(4); var actionManager = await createActionManager({ actions: this.actions, @@ -2345,11 +2349,11 @@ QUnit.module('ActionManager', { }); await actionManager.doAction(3); - assert.isNotVisible(actionManager.$('.o_cp_sidebar button.o_dropdown_toggler_btn:contains("Print")')); - assert.isNotVisible(actionManager.$('.o_cp_sidebar button.o_dropdown_toggler_btn:contains("Action")')); + assert.containsNone(actionManager, '.o_cp_action_menus'); + await testUtils.dom.clickFirst(actionManager.$('input.custom-control-input')); - assert.isVisible(actionManager.$('.o_cp_sidebar button.o_dropdown_toggler_btn:contains("Print")')); - assert.isVisible(actionManager.$('.o_cp_sidebar button.o_dropdown_toggler_btn:contains("Action")')); + assert.isVisible(actionManager.$('.o_cp_action_menus button.o_dropdown_toggler_btn:contains("Print")')); + assert.isVisible(actionManager.$('.o_cp_action_menus button.o_dropdown_toggler_btn:contains("Action")')); actionManager.destroy(); }); @@ -2372,14 +2376,14 @@ QUnit.module('ActionManager', { "should display the list view"); // switch to kanban view - await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban')); + await cpHelpers.switchView(actionManager, 'kanban'); assert.containsNone(actionManager, '.o_list_view', "should no longer display the list view"); assert.containsOnce(actionManager, '.o_kanban_view', "should display the kanban view"); // switch back to list view - await testUtils.dom.click($('.o_control_panel .o_cp_switch_list')); + await cpHelpers.switchView(actionManager, 'list'); assert.containsOnce(actionManager, '.o_list_view', "should display the list view"); assert.containsNone(actionManager, '.o_kanban_view', @@ -2486,7 +2490,7 @@ QUnit.module('ActionManager', { "breadcrumbs should display the display_name of the action"); // switch to kanban view - await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban')); + await cpHelpers.switchView(actionManager, 'kanban'); assert.strictEqual($('.o_control_panel .breadcrumb-item').length, 1, "there should still be one controller in the breadcrumbs"); assert.strictEqual($('.o_control_panel .breadcrumb-item').text(), 'Partners', @@ -2508,7 +2512,7 @@ QUnit.module('ActionManager', { "breadcrumbs should display the display_name of the action"); // switch back to list view - await testUtils.dom.click($('.o_control_panel .o_cp_switch_list')); + await cpHelpers.switchView(actionManager, 'list'); assert.strictEqual($('.o_control_panel .breadcrumb-item').length, 1, "there should still be one controller in the breadcrumbs"); assert.strictEqual($('.o_control_panel .breadcrumb-item').text(), 'Partners', @@ -2543,43 +2547,43 @@ QUnit.module('ActionManager', { }); await actionManager.doAction(3); - assert.strictEqual($('.o_control_panel .o_cp_switch_buttons button').length, 2, + assert.containsN(actionManager, '.o_control_panel button.o_switch_view', 2, "should have two switch buttons (list and kanban)"); - assert.strictEqual($('.o_control_panel .o_cp_switch_buttons button.active').length, 1, + assert.containsOnce(actionManager, '.o_control_panel button.o_switch_view.active', "should have only one active button"); - assert.hasClass($('.o_control_panel .o_cp_switch_buttons button:first'),'o_cp_switch_list', + assert.hasClass($('.o_control_panel .o_switch_view:first'),'o_list', "list switch button should be the first one"); - assert.hasClass($('.o_control_panel .o_cp_switch_list'),'active', + assert.hasClass($('.o_control_panel .o_switch_view.o_list'), 'active', "list should be the active view"); // switch to kanban view - await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban')); - assert.strictEqual($('.o_control_panel .o_cp_switch_buttons button').length, 2, + await cpHelpers.switchView(actionManager, 'kanban'); + assert.containsN(actionManager, '.o_control_panel .o_switch_view', 2, "should still have two switch buttons (list and kanban)"); - assert.strictEqual($('.o_control_panel .o_cp_switch_buttons button.active').length, 1, + assert.containsOnce(actionManager, '.o_control_panel .o_switch_view.active', "should still have only one active button"); - assert.hasClass($('.o_control_panel .o_cp_switch_buttons button:first'),'o_cp_switch_list', + assert.hasClass($('.o_control_panel .o_switch_view:first'), 'o_list', "list switch button should still be the first one"); - assert.hasClass($('.o_control_panel .o_cp_switch_kanban'),'active', + assert.hasClass($('.o_control_panel .o_switch_view.o_kanban'),'active', "kanban should now be the active view"); // switch back to list view - await testUtils.dom.click($('.o_control_panel .o_cp_switch_list')); - assert.strictEqual($('.o_control_panel .o_cp_switch_buttons button').length, 2, + await cpHelpers.switchView(actionManager, 'list'); + assert.containsN(actionManager, '.o_control_panel .o_switch_view', 2, "should still have two switch buttons (list and kanban)"); - assert.hasClass($('.o_control_panel .o_cp_switch_list'),'active', + assert.hasClass($('.o_control_panel .o_switch_view.o_list'),'active', "list should now be the active view"); // open a record in form view await testUtils.dom.click(actionManager.$('.o_list_view .o_data_row:first')); - assert.strictEqual($('.o_control_panel .o_cp_switch_buttons button').length, 0, + assert.containsNone(actionManager, '.o_control_panel .o_switch_view', "should not have any switch buttons"); // go back to list view using the breadcrumbs await testUtils.dom.click($('.o_control_panel .breadcrumb a')); - assert.strictEqual($('.o_control_panel .o_cp_switch_buttons button').length, 2, + assert.containsN(actionManager, '.o_control_panel .o_switch_view', 2, "should have two switch buttons (list and kanban)"); - assert.hasClass($('.o_control_panel .o_cp_switch_list'),'active', + assert.hasClass($('.o_control_panel .o_switch_view.o_list'),'active', "list should be the active view"); actionManager.destroy(); @@ -2601,7 +2605,7 @@ QUnit.module('ActionManager', { "limit should be correct for kanban"); // switch to list view - await testUtils.dom.click($('.o_control_panel .o_cp_switch_list')); + await cpHelpers.switchView(actionManager, 'list'); assert.strictEqual($('.o_control_panel .o_pager_value').text(), '1-3', "value should be correct for list"); assert.strictEqual($('.o_control_panel .o_pager_limit').text(), '5', @@ -2622,7 +2626,7 @@ QUnit.module('ActionManager', { "limit should be correct for list"); // switch back to kanban view - await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban')); + await cpHelpers.switchView(actionManager, 'kanban'); assert.strictEqual($('.o_control_panel .o_pager_value').text(), '1-5', "value should be correct for kanban"); assert.strictEqual($('.o_control_panel .o_pager_limit').text(), '5', @@ -2646,12 +2650,12 @@ QUnit.module('ActionManager', { assert.containsN(actionManager, '.o_data_row', 5); // activate a domain - await testUtils.dom.click(actionManager.$('.o_search_options .o_filters_menu_button')); - await testUtils.dom.click(actionManager.$('.o_search_options .o_filters_menu a:contains(Bar)')); + await cpHelpers.toggleFilterMenu(actionManager); + await cpHelpers.toggleMenuItem(actionManager, "Bar"); assert.containsN(actionManager, '.o_data_row', 2); // switch to kanban - await testUtils.dom.click(actionManager.$('.o_control_panel .o_cp_switch_kanban')); + await cpHelpers.switchView(actionManager, 'kanban'); assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 2); // remove the domain @@ -2659,7 +2663,7 @@ QUnit.module('ActionManager', { assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 5); // switch back to list - await testUtils.dom.click(actionManager.$('.o_control_panel .o_cp_switch_list')); + await cpHelpers.switchView(actionManager, 'list'); assert.containsN(actionManager, '.o_data_row', 5); actionManager.destroy(); @@ -2682,7 +2686,7 @@ QUnit.module('ActionManager', { // switch to kanban view def = testUtils.makeTestPromise(); - await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban')); + await cpHelpers.switchView(actionManager, 'kanban'); assert.containsOnce(actionManager, '.o_list_view', "should still display the list view"); assert.containsNone(actionManager, '.o_kanban_view', @@ -2696,7 +2700,7 @@ QUnit.module('ActionManager', { // switch back to list view def = testUtils.makeTestPromise(); - await testUtils.dom.click($('.o_control_panel .o_cp_switch_list')); + await cpHelpers.switchView(actionManager, 'list'); assert.containsOnce(actionManager, '.o_kanban_view', "should still display the kanban view"); assert.containsNone(actionManager, '.o_list_view', @@ -3044,11 +3048,11 @@ QUnit.module('ActionManager', { "line chart button is now active"); // switch to kanban and back to graph view - await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban')); + await cpHelpers.switchView(actionManager, 'kanban'); assert.strictEqual($('.o_control_panel .fa-area-chart').length, 0, "graph buttons are no longer in control panel"); - await testUtils.dom.click($('.o_control_panel .o_cp_switch_graph')); + await cpHelpers.switchView(actionManager, 'graph'); assert.hasClass($('.o_control_panel .fa-area-chart'),'active', "line chart button is still active"); actionManager.destroy(); @@ -3069,16 +3073,16 @@ QUnit.module('ActionManager', { }); await actionManager.doAction(3); - assert.hasClass($('.o_control_panel .o_cp_switch_list'),'active', + assert.hasClass($('.o_control_panel .o_switch_view.o_list'),'active', "list button in control panel is active"); - assert.doesNotHaveClass($('.o_control_panel .o_cp_switch_graph'), 'active', + assert.doesNotHaveClass($('.o_control_panel .o_switch_view.o_graph'), 'active', "graph button in control panel is not active"); // switch to graph view - await testUtils.dom.click($('.o_control_panel .o_cp_switch_graph')); - assert.doesNotHaveClass($('.o_control_panel .o_cp_switch_list'), 'active', + await cpHelpers.switchView(actionManager, 'graph'); + assert.doesNotHaveClass($('.o_control_panel .o_switch_view.o_list'), 'active', "list button in control panel is not active"); - assert.hasClass($('.o_control_panel .o_cp_switch_graph'),'active', + assert.hasClass($('.o_control_panel .o_switch_view.o_graph'),'active', "graph button in control panel is active"); actionManager.destroy(); }); @@ -3222,7 +3226,7 @@ QUnit.module('ActionManager', { "should only display 2 record"); // switch to kanban view - await testUtils.dom.click($('.o_control_panel .o_cp_switch_kanban')); + await cpHelpers.switchView(actionManager, 'kanban'); assert.strictEqual(actionManager.$('.o_kanban_record:not(.o_kanban_ghost)').length, 2, "should only display 2 record"); @@ -3412,14 +3416,19 @@ QUnit.module('ActionManager', { actions: this.actions, archs: this.archs, data: this.data, - intercepts: { - create_filter: function (event) { - var filter = event.data.filter; - assert.deepEqual(filter.domain, `[("bar", "=", 1)]`, - "should save the correct domain"); - assert.deepEqual(filter.context, {shouldBeInFilterContext: true}, - "should save the correct context"); - }, + env: { + dataManager: { + create_filter: function (filter) { + assert.strictEqual(filter.domain, `[("bar", "=", 1)]`, + "should save the correct domain"); + const expectedContext = { + group_by: [], // default groupby is an empty list + shouldBeInFilterContext: true, + }; + assert.deepEqual(filter.context, expectedContext, + "should save the correct context"); + }, + } }, }); await actionManager.doAction(33); @@ -3428,16 +3437,16 @@ QUnit.module('ActionManager', { "should contain 5 records"); // filter on bar - await testUtils.dom.click($('.o_control_panel .o_search_options .o_dropdown_toggler_btn:contains(Filters)')); - await testUtils.dom.click($('.o_control_panel .o_filters_menu a:contains(Bar)')); + await cpHelpers.toggleFilterMenu(actionManager); + await cpHelpers.toggleMenuItem(actionManager, "Bar"); assert.containsN(actionManager, '.o_data_row', 2); // save filter - await testUtils.dom.click($('.o_control_panel .o_search_options .o_dropdown_toggler_btn:contains(Favorites)')); - await testUtils.dom.click($('.o_control_panel .o_add_favorite')); - $('.o_control_panel .o_favorite_name input[type=text]').val('some name'); // name the filter - await testUtils.dom.click($('.o_control_panel .o_save_favorite button')); + await cpHelpers.toggleFavoriteMenu(actionManager); + await cpHelpers.toggleSaveFavorite(actionManager); + await cpHelpers.editFavoriteName(actionManager, "some name"); + await cpHelpers.saveFavorite(actionManager); testUtils.mock.unpatch(ListController); actionManager.destroy(); @@ -3460,29 +3469,23 @@ QUnit.module('ActionManager', { actions: this.actions, archs: this.archs, data: this.data, - intercepts: { - load_filters: function (ev) { - ev.data.on_success([ - { - user_id: [2, "Mitchell Admin"], - name: 'favorite filter', - id: 5, - context: {}, - sort: '[]', - domain: '[("bar", "=", 1)]' - } - ]); - }, - }, + favoriteFilters: [{ + user_id: [2, "Mitchell Admin"], + name: 'favorite filter', + id: 5, + context: {}, + sort: '[]', + domain: '[("bar", "=", 1)]' + }], }); - await actionManager.doAction(12); + assert.strictEqual(actionManager.$('.o_list_view tr.o_data_row .o_data_cell').text(), 'zoupyopplopgnapblip', 'record should be in descending order as default_order applies'); - // apply favorite filter - await testUtils.dom.click(actionManager.$('.o_favorites_menu_button')); - await testUtils.dom.click(actionManager.$('.o_menu_item a:contains("favorite filter")')); + await cpHelpers.toggleFavoriteMenu(actionManager); + await cpHelpers.toggleMenuItem(actionManager, "favorite filter"); + assert.strictEqual(actionManager.$('.o_control_panel .o_facet_values').text().trim(), 'favorite filter', 'favorite filter should be applied'); assert.strictEqual(actionManager.$('.o_list_view tr.o_data_row .o_data_cell').text(), 'gnapblip', @@ -3495,7 +3498,7 @@ QUnit.module('ActionManager', { 'order of records should not be changed, while coming back through breadcrumb'); // remove filter - await testUtils.dom.click(actionManager.$('.o_searchview .o_facet_remove')); + await cpHelpers.removeFacet(actionManager, 0); assert.strictEqual(actionManager.$('.o_list_view tr.o_data_row .o_data_cell').text(), 'zoupyopplopgnapblip', 'order of records should not be changed, after removing current filter'); @@ -3512,16 +3515,16 @@ QUnit.module('ActionManager', { }); await actionManager.doAction(1); - assert.strictEqual($('.o_search_options .o_dropdown:visible .o_filters_menu').length, 1, + assert.isVisible(actionManager.el.querySelector('.o_search_options .o_dropdown.o_filter_menu'), "the search options should be available"); await actionManager.doAction(3); - assert.strictEqual($('.o_search_options .o_dropdown:visible .o_filters_menu').length, 1, + assert.isVisible(actionManager.el.querySelector('.o_search_options .o_dropdown.o_filter_menu'), "the search options should be available"); // go back using the breadcrumbs await testUtils.dom.click($('.o_control_panel .breadcrumb a:first')); - assert.strictEqual($('.o_search_options .o_dropdown:visible .o_filters_menu').length, 1, + assert.isVisible(actionManager.el.querySelector('.o_search_options .o_dropdown.o_filter_menu'), "the search options should be available"); actionManager.destroy(); @@ -3772,11 +3775,11 @@ QUnit.module('ActionManager', { }); await actionManager.doAction(5); - assert.strictEqual($('.o_technical_modal .modal-body button.infooter').length, 0, + assert.containsNone($('.o_technical_modal .modal-body'), 'button.infooter', "the button should not be in the body"); - assert.strictEqual($('.o_technical_modal .modal-footer button.infooter').length, 1, + assert.containsOnce($('.o_technical_modal .modal-footer'), 'button.infooter', "the button should be in the footer"); - assert.strictEqual($('.o_technical_modal .modal-footer button').length, 1, + assert.containsOnce($('.o_technical_modal .modal-footer'), 'button', "the modal footer should only contain one button"); actionManager.destroy(); @@ -4235,7 +4238,7 @@ QUnit.module('ActionManager', {
-