summaryrefslogtreecommitdiff
path: root/addons/web
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web')
-rw-r--r--addons/web/static/tests/chrome/action_manager_tests.js206
-rw-r--r--addons/web/static/tests/chrome/pager_tests.js93
-rw-r--r--addons/web/static/tests/components/custom_file_input_tests.js141
-rw-r--r--addons/web/static/tests/fields/basic_fields_tests.js91
-rw-r--r--addons/web/static/tests/fields/relational_fields/field_many2many_tests.js6
-rw-r--r--addons/web/static/tests/fields/relational_fields/field_many2one_tests.js22
-rw-r--r--addons/web/static/tests/fields/relational_fields/field_one2many_tests.js33
-rw-r--r--addons/web/static/tests/fields/relational_fields_tests.js31
-rw-r--r--addons/web/static/tests/views/calendar_tests.js2
-rw-r--r--addons/web/static/tests/views/form_tests.js199
-rw-r--r--addons/web/static/tests/views/graph_tests.js150
-rw-r--r--addons/web/static/tests/views/kanban_tests.js33
-rw-r--r--addons/web/static/tests/views/list_tests.js285
-rw-r--r--addons/web/static/tests/views/pivot_tests.js198
-rw-r--r--addons/web/static/tests/views/qweb_tests.js1
-rw-r--r--addons/web/static/tests/views/search_filter_menu_tests.js206
-rw-r--r--addons/web/static/tests/views/search_groupby_menu_tests.js200
-rw-r--r--addons/web/static/tests/views/search_panel_tests.js45
-rw-r--r--addons/web/static/tests/views/search_view_tests.js1928
-rw-r--r--addons/web/static/tests/views/view_dialogs_tests.js68
-rw-r--r--addons/web/static/tests/widgets/data_export_tests.js38
-rw-r--r--addons/web/static/tests/widgets/dropdown_menu_tests.js203
22 files changed, 793 insertions, 3386 deletions
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', {
<t t-name="kanban-box">
<div class="oe_kanban_global_click">
<field name="display_name"/>
- <button
+ <button
name="1"
string="Execute action"
type="action"
@@ -4294,28 +4297,21 @@ QUnit.module('ActionManager', {
return this._super.apply(this, arguments);
},
});
-
await actionManager.doAction(3);
- var $searchInput = $('.o_searchview input');
- $searchInput.val('m'); // the searchbar checks the contents of the input on keypress events
- await testUtils.fields.triggerKey('press', $searchInput, 'm');
- await testUtils.fields.triggerKeydown($searchInput, 'enter');
+ await cpHelpers.editSearch(actionManager, "m");
+ await cpHelpers.validateSearch(actionManager);
- assert.verifySteps(["search_read ",
- "search_read foo,ilike,m"]);
+ assert.verifySteps(["search_read ", "search_read foo,ilike,m"]);
// Triggering the do_search above will kill the current searchview Input
- $searchInput = $('.o_searchview input');
- $searchInput.val('o'); // the searchbar checks the contents of the input on keypress events
- await testUtils.fields.triggerKey('press', $searchInput, 'o');
+ await cpHelpers.editSearch(actionManager, "o");
// We have something in the input of the search view. Making the search_read
// return at this point will trigger the redraw of the view.
// However we want to hold on to what we just typed
searchPromise.resolve();
- await testUtils.nextTick();
- await testUtils.fields.triggerKeydown($searchInput, 'enter');
+ await cpHelpers.validateSearch(actionManager);
assert.verifySteps(["search_read |,foo,ilike,m,foo,ilike,o"]);
diff --git a/addons/web/static/tests/chrome/pager_tests.js b/addons/web/static/tests/chrome/pager_tests.js
deleted file mode 100644
index 18a4ae7fc37..00000000000
--- a/addons/web/static/tests/chrome/pager_tests.js
+++ /dev/null
@@ -1,93 +0,0 @@
-odoo.define('web.pager_tests', function (require) {
-"use strict";
-
-var Pager = require('web.Pager');
-var concurrency = require('web.concurrency');
-var testUtils = require('web.test_utils');
-
-QUnit.module('chrome', {}, function () {
-
- QUnit.module('Pager');
-
- QUnit.test('basic stuff', async function (assert) {
- assert.expect(2);
-
- var pager = new Pager(null, 10, 1, 4);
- pager.appendTo($('#qunit-fixture'));
- await testUtils.nextTick();
-
- assert.strictEqual(pager.state.current_min, 1,
- "current_min should be set to 1");
-
- // click on next
- await testUtils.dom.click(pager.$('.o_pager_next'));
- assert.strictEqual(pager.state.current_min, 5,
- "current_min should now be 5");
-
- pager.destroy();
- });
-
- QUnit.test('edit the pager', async function (assert) {
- assert.expect(5);
-
- var pager = new Pager(null, 10, 1, 4);
- pager.appendTo($('#qunit-fixture'));
- await testUtils.nextTick();
-
- // enter edition
- await testUtils.dom.click(pager.$('.o_pager_value'));
- assert.containsOnce(pager, 'input',
- "the pager should contain an input");
- assert.strictEqual(pager.$('input').val(), '1-4',
- "the input should have correct value");
-
- // change the limit
- await testUtils.fields.editInput(pager.$('input'), '1-6');
- await testUtils.fields.triggerKeydown(pager.$('input'), 'enter');
- assert.strictEqual(pager.state.limit, 6,
- "the limit should have been updated");
- assert.strictEqual(pager.state.current_min, 1,
- "the current_min should not have changed");
- assert.strictEqual(pager.$('.o_pager_value').text(), '1-6',
- "the input should have correct value");
-
- pager.destroy();
- });
-
- QUnit.test('disabling the pager', async function (assert) {
- assert.expect(4);
-
- var pager = new Pager(null, 10, 1, 4);
- pager.appendTo($('#qunit-fixture'));
- await testUtils.nextTick();
- await pager.disable();
-
- // try to go to the next or previous pages
- await testUtils.dom.click(pager.$('.o_pager_next'));
- assert.strictEqual(pager.state.current_min, 1,
- "current_min should still be 1");
- await testUtils.dom.click(pager.$('.o_pager_previous'));
- assert.strictEqual(pager.state.current_min, 1,
- "current_min should still be 1");
-
- // try to change the limit
- await testUtils.dom.click(pager.$('.o_pager_value'));
- assert.containsNone(pager, 'input',
- "the pager should not contain an input");
-
- // a common use is to disable the pager before reloading the data, and
- // re-enable it once they have been loaded
- // the following emulates this situation
- pager.on('pager_changed', null, function () {
- pager.disable();
- concurrency.delay(0).then(function () {
- assert.ok(pager.disabled, "pager should still be disabled");
- pager.destroy();
- });
- });
- pager.enable();
- await testUtils.dom.click(pager.$('.o_pager_next'));
- });
-});
-
-});
diff --git a/addons/web/static/tests/components/custom_file_input_tests.js b/addons/web/static/tests/components/custom_file_input_tests.js
index 0131213f6e9..279bf67f11b 100644
--- a/addons/web/static/tests/components/custom_file_input_tests.js
+++ b/addons/web/static/tests/components/custom_file_input_tests.js
@@ -2,102 +2,89 @@ odoo.define('web.custom_file_input_tests', function (require) {
"use strict";
const CustomFileInput = require('web.CustomFileInput');
- const makeTestEnvironment = require('web.test_env');
const testUtils = require('web.test_utils');
- const { Component, tags, useState } = owl;
- const { xml } = tags;
+ const { createComponent } = testUtils;
QUnit.module('Components', {}, function () {
// This module cannot be tested as thoroughly as we want it to be:
// browsers do not let scripts programmatically assign values to inputs
// of type file
- QUnit.module('CustomFileInput', {}, function () {
- QUnit.test("Rendering of all props", async function (assert) {
- assert.expect(12);
-
- class Parent extends Component {
- constructor() {
- super(...arguments);
- this.state = useState({ innerContent: '<a href="#">Trigger</a>' });
- }
- // Handlers
- _onFileUploaded(ev) {
- assert.strictEqual(ev.detail.files.length, 0,
- "'files' property should be an empty array");
- }
- }
- Parent.components = { CustomFileInput };
- Parent.env = makeTestEnvironment({
+ QUnit.module('CustomFileInput');
+
+ QUnit.test("Upload a file: default props", async function (assert) {
+ assert.expect(6);
+
+ const customFileInput = await createComponent(CustomFileInput, {
+ env: {
+ services: {
+ async httpRequest(route, params) {
+ assert.deepEqual(params, {
+ csrf_token: odoo.csrf_token,
+ ufile: [],
+ });
+ assert.step(route);
+ return '[]';
+ },
+ },
+ },
+ });
+ const input = customFileInput.el.querySelector('input');
+
+ assert.strictEqual(customFileInput.el.innerText.trim().toUpperCase(), "CHOOSE FILE",
+ "File input total text should match its given inner element's text");
+ assert.strictEqual(input.accept, '*',
+ "Input should accept all files by default");
+
+ await testUtils.dom.triggerEvent(input, 'change');
+
+ assert.notOk(input.multiple, "'multiple' attribute should not be set");
+ assert.verifySteps(['/web/binary/upload']);
+
+ customFileInput.destroy();
+ });
+
+ QUnit.test("Upload a file: custom attachment", async function (assert) {
+ assert.expect(6);
+
+ const customFileInput = await createComponent(CustomFileInput, {
+ env: {
services: {
- httpRequest: (route, params) => {
- if (route === '/web/binary/upload') {
- assert.deepEqual(params, {
- csrf_token: odoo.csrf_token,
- ufile: [],
- });
- assert.step(route);
- return Promise.resolve('[]');
- } else if (route === '/web/binary/upload_attachment') {
- assert.deepEqual(params, {
- id: 5,
- model: 'res.model',
- csrf_token: odoo.csrf_token,
- ufile: [],
- });
- assert.step(route);
- return Promise.resolve('[]');
- }
+ async httpRequest(route, params) {
+ assert.deepEqual(params, {
+ id: 5,
+ model: 'res.model',
+ csrf_token: odoo.csrf_token,
+ ufile: [],
+ });
+ assert.step(route);
+ return '[]';
},
},
- });
- Parent.template = xml`
- <CustomFileInput
- accepted_file_extensions="state.accepted_file_extensions"
- action="state.action"
- id="state.id"
- model="state.model"
- multi_upload="state.multi_upload"
- t-on-uploaded="_onFileUploaded"
- >
- <t t-raw="state.innerContent"/>
- </CustomFileInput>`;
-
- const parent = new Parent();
- await parent.mount(testUtils.prepareTarget());
- const fileInput = parent.el;
- const input = fileInput.querySelector('input');
-
- // Default props
- assert.strictEqual(fileInput.innerText.trim(), "Trigger",
- "File input total text should match its given inner element's text");
- assert.strictEqual(input.accept, '*',
- "Input should accept all files by default");
- await testUtils.dom.triggerEvent(input, 'change');
- assert.notOk(input.multiple,
- "'multiple' attribute should not be set");
-
- // Change props
- Object.assign(parent.state, {
+ },
+ props: {
accepted_file_extensions: '.png',
action: '/web/binary/upload_attachment',
id: 5,
model: 'res.model',
multi_upload: true,
- });
- await testUtils.nextTick();
+ },
+ intercepts: {
+ 'uploaded': ev => assert.strictEqual(ev.detail.files.length, 0,
+ "'files' property should be an empty array"),
+ },
+ });
+ const input = customFileInput.el.querySelector('input');
- assert.strictEqual(input.accept, '.png',
- "Input should now only accept pngs");
- await testUtils.dom.triggerEvent(input, 'change');
- assert.ok(input.multiple,
- "'multiple' attribute should be set");
+ assert.strictEqual(input.accept, '.png', "Input should now only accept pngs");
- assert.verifySteps(['/web/binary/upload', '/web/binary/upload_attachment']);
+ await testUtils.dom.triggerEvent(input, 'change');
- parent.destroy();
- });
+ assert.ok(input.multiple, "'multiple' attribute should be set");
+ assert.verifySteps(['/web/binary/upload_attachment']);
+
+ customFileInput.destroy();
});
});
});
diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js
index ada71b91429..eaa41651c20 100644
--- a/addons/web/static/tests/fields/basic_fields_tests.js
+++ b/addons/web/static/tests/fields/basic_fields_tests.js
@@ -19,6 +19,10 @@ var DebouncedField = basicFields.DebouncedField;
var JournalDashboardGraph = basicFields.JournalDashboardGraph;
var _t = core._t;
+// Base64 images for testing purpose
+const MY_IMAGE = 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
+const PRODUCT_IMAGE = 'R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7';
+
QUnit.module('fields', {}, function () {
QUnit.module('basic_fields', {
@@ -2516,7 +2520,7 @@ QUnit.module('basic_fields', {
assert.expect(7);
this.data.partner.records[0].__last_update = '2017-02-08 10:00:00';
- this.data.partner.records[0].document = 'myimage';
+ this.data.partner.records[0].document = MY_IMAGE;
var form = await createView({
View: FormView,
@@ -2526,13 +2530,13 @@ QUnit.module('basic_fields', {
'<field name="document" widget="image" options="{\'size\': [90, 90]}"/> ' +
'</form>',
res_id: 1,
- mockRPC: function (route, args) {
+ async mockRPC(route, args) {
if (route === '/web/dataset/call_kw/partner/read') {
assert.deepEqual(args.args[1], ['document', '__last_update', 'display_name'], "The fields document, display_name and __last_update should be present when reading an image");
}
- if (route === 'data:image/png;base64,myimage') {
+ if (route === `data:image/png;base64,${MY_IMAGE}`) {
assert.ok(true, "should called the correct route");
- return Promise.resolve('wow');
+ return 'wow';
}
return this._super.apply(this, arguments);
},
@@ -2551,6 +2555,59 @@ QUnit.module('basic_fields', {
form.destroy();
});
+ QUnit.test('image fields are correctly replaced when given an incorrect value', async function (assert) {
+ assert.expect(7);
+
+ this.data.partner.records[0].__last_update = '2017-02-08 10:00:00';
+ this.data.partner.records[0].document = 'incorrect_base64_value';
+
+ testUtils.mock.patch(basicFields.FieldBinaryImage, {
+ // Delay the _render function: this will ensure that the error triggered
+ // by the incorrect base64 value is dispatched before the src is replaced
+ // (see test_utils_mock.removeSrcAttribute), since that function is called
+ // when the element is inserted into the DOM.
+ async _render() {
+ const result = this._super.apply(this, arguments);
+ await concurrency.delay(100);
+ return result;
+ },
+ });
+
+ const form = await createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch: `
+ <form string="Partners">
+ <field name="document" widget="image" options="{'size': [90, 90]}"/>
+ </form>`,
+ res_id: 1,
+ async mockRPC(route, args) {
+ const _super = this._super;
+ if (route === '/web/static/src/img/placeholder.png') {
+ assert.step('call placeholder route');
+ }
+ return _super.apply(this, arguments);
+ },
+ });
+
+ assert.hasClass(form.$('div[name="document"]'),'o_field_image',
+ "the widget should have the correct class");
+ assert.containsOnce(form, 'div[name="document"] > img',
+ "the widget should contain an image");
+ assert.hasClass(form.$('div[name="document"] > img'), 'img-fluid',
+ "the image should have the correct class");
+ assert.hasAttrValue(form.$('div[name="document"] > img'), 'width', "90",
+ "the image should correctly set its attributes");
+ assert.strictEqual(form.$('div[name="document"] > img').css('max-width'), "90px",
+ "the image should correctly set its attributes");
+
+ assert.verifySteps(['call placeholder route']);
+
+ form.destroy();
+ testUtils.mock.unpatch(basicFields.FieldBinaryImage);
+ });
+
QUnit.test('image: option accepted_file_extensions', async function (assert) {
assert.expect(2);
@@ -2583,9 +2640,9 @@ QUnit.module('basic_fields', {
assert.expect(6);
this.data.partner.records[0].__last_update = '2017-02-08 10:00:00';
- this.data.partner.records[0].document = 'myimage';
+ this.data.partner.records[0].document = MY_IMAGE;
this.data.partner_type.fields.image = {name: 'image', type: 'binary'};
- this.data.partner_type.records[0].image = 'product_image';
+ this.data.partner_type.records[0].image = PRODUCT_IMAGE;
this.data.partner.records[0].timmy = [12];
var form = await createView({
@@ -2604,14 +2661,14 @@ QUnit.module('basic_fields', {
'</field>' +
'</form>',
res_id: 1,
- mockRPC: function (route) {
- if (route === 'data:image/png;base64,myimage') {
+ async mockRPC(route) {
+ if (route === `data:image/png;base64,${MY_IMAGE}`) {
assert.step("The view's image should have been fetched");
- return Promise.resolve('wow');
+ return 'wow';
}
- if (route === 'data:image/png;base64,product_image') {
+ if (route === `data:image/gif;base64,${PRODUCT_IMAGE}`) {
assert.step("The dialog's image should have been fetched");
- return Promise.resolve();
+ return;
}
return this._super.apply(this, arguments);
},
@@ -2634,7 +2691,7 @@ QUnit.module('basic_fields', {
assert.expect(2);
this.data.partner_type.fields.image = {name: 'image', type: 'binary'};
- this.data.partner_type.records[0].image = 'product_image';
+ this.data.partner_type.records[0].image = PRODUCT_IMAGE;
this.data.partner.records[0].timmy = [12];
var form = await createView({
@@ -2649,10 +2706,10 @@ QUnit.module('basic_fields', {
'</field>' +
'</form>',
res_id: 1,
- mockRPC: function (route) {
- if (route === 'data:image/png;base64,product_image') {
+ async mockRPC(route) {
+ if (route === `data:image/gif;base64,${PRODUCT_IMAGE}`) {
assert.ok(true, "The list's image should have been fetched");
- return Promise.resolve();
+ return;
}
return this._super.apply(this, arguments);
},
@@ -2961,7 +3018,7 @@ QUnit.module('basic_fields', {
QUnit.module('FieldDateRange');
- QUnit.test('Datetime field', async function (assert) {
+ QUnit.test('Datetime field [REQUIRE FOCUS]', async function (assert) {
assert.expect(20);
this.data.partner.fields.datetime_end = {string: 'Datetime End', type: 'datetime'};
@@ -3039,7 +3096,7 @@ QUnit.module('basic_fields', {
form.destroy();
});
- QUnit.test('Date field', async function (assert) {
+ QUnit.test('Date field [REQUIRE FOCUS]', async function (assert) {
assert.expect(18);
this.data.partner.fields.date_end = {string: 'Date End', type: 'date'};
diff --git a/addons/web/static/tests/fields/relational_fields/field_many2many_tests.js b/addons/web/static/tests/fields/relational_fields/field_many2many_tests.js
index a1c306a432c..47fe687d773 100644
--- a/addons/web/static/tests/fields/relational_fields/field_many2many_tests.js
+++ b/addons/web/static/tests/fields/relational_fields/field_many2many_tests.js
@@ -3,6 +3,8 @@ odoo.define('web.field_many_to_many_tests', function (require) {
var FormView = require('web.FormView');
var testUtils = require('web.test_utils');
+
+const cpHelpers = testUtils.controlPanel;
var createView = testUtils.createView;
QUnit.module('fields', {}, function () {
@@ -1003,8 +1005,8 @@ QUnit.module('fields', {}, function () {
assert.strictEqual($('.modal .o_data_row').length, 1,
"should contain only one row (gold)");
- await testUtils.fields.triggerKey('press', $('.modal .o_searchview_input'), 's');
- await testUtils.fields.triggerKeydown($('.modal .o_searchview_input'), 'enter');
+ await cpHelpers.editSearch('.modal', 's');
+ await cpHelpers.validateSearch('.modal');
assert.strictEqual($('.modal .o_data_row').length, 0, "should contain no row");
diff --git a/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js b/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js
index 21d74bf0d99..04c934290a1 100644
--- a/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js
+++ b/addons/web/static/tests/fields/relational_fields/field_many2one_tests.js
@@ -9,6 +9,7 @@ var StandaloneFieldManagerMixin = require('web.StandaloneFieldManagerMixin');
var testUtils = require('web.test_utils');
var Widget = require('web.Widget');
+const cpHelpers = testUtils.controlPanel;
var createView = testUtils.createView;
QUnit.module('fields', {}, function () {
@@ -244,11 +245,11 @@ QUnit.module('fields', {}, function () {
// save form
await testUtils.form.clickSave(form);
// click next on pager
- await testUtils.dom.click(form.pager.$('.o_pager_next'));
+ await testUtils.dom.click(form.el.querySelector('.o_pager .o_pager_next'));
// this checks that the view did not ask for confirmation that the
// record is dirty
- assert.strictEqual(form.pager.$el.text().trim(), '2 / 2',
+ assert.strictEqual(form.el.querySelector('.o_pager').innerText.trim(), '2 / 2',
'pager should be at second page');
form.destroy();
});
@@ -316,11 +317,11 @@ QUnit.module('fields', {}, function () {
// save form
await testUtils.form.clickSave(form);
// click next on pager
- await testUtils.dom.click(form.pager.$('.o_pager_next'));
+ await testUtils.dom.click(form.el.querySelector('.o_pager .o_pager_next'));
// this checks that the view did not ask for confirmation that the
// record is dirty
- assert.strictEqual(form.pager.$el.text().trim(), '2 / 2',
+ assert.strictEqual(form.el.querySelector('.o_pager').innerText.trim(), '2 / 2',
'pager should be at second page');
form.destroy();
});
@@ -506,11 +507,11 @@ QUnit.module('fields', {}, function () {
assert.strictEqual($('tr.o_data_row').length, 9, "should display 9 records");
- await testUtils.dom.click($('button:contains(Filters)'));
- await testUtils.dom.click($('.o_add_custom_filter:visible'));
- assert.strictEqual($('.o_filter_condition select.o_searchview_extended_prop_field').val(), 'datetime',
+ await cpHelpers.toggleFilterMenu('.modal');
+ await cpHelpers.toggleAddCustomFilter('.modal');
+ assert.strictEqual(document.querySelector('.modal .o_generator_menu_field').value, 'datetime',
"datetime field should be selected");
- await testUtils.dom.click($('.o_apply_filter'));
+ await cpHelpers.applyFilter('.modal');
assert.strictEqual($('tr.o_data_row').length, 0, "should display 0 records");
form.destroy();
@@ -592,7 +593,6 @@ QUnit.module('fields', {}, function () {
assert.containsNone(document.body, '.modal',
"No save should be triggered when removing value");
- await testUtils.fields.many2one.clickOpenDropdown('trululu');
await testUtils.fields.many2one.clickHighlightedItem('trululu');
assert.containsOnce(document.body, '.modal',
@@ -741,8 +741,8 @@ QUnit.module('fields', {}, function () {
assert.ok(!$('.modal .modal-footer .o_select_button').length,
"there should be no 'Select' button in the footer");
assert.ok($('.modal tbody tr').length > 10, "list should contain more than 10 records");
- await testUtils.fields.triggerKey('press', $('.modal .o_searchview_input'), 'P'),
- await testUtils.fields.triggerKeydown($('.modal .o_searchview_input'), 'enter');
+ await cpHelpers.editSearch('.modal', "P");
+ await cpHelpers.validateSearch('.modal');
assert.strictEqual($('.modal tbody tr').length, 10,
"list should be restricted to records containing a P (10 records)");
// choose a record
diff --git a/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js b/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js
index e24341b1019..e93dc2f39ca 100644
--- a/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js
+++ b/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js
@@ -12,6 +12,7 @@ var relationalFields = require('web.relational_fields');
var testUtils = require('web.test_utils');
var fieldUtils = require('web.field_utils');
+const cpHelpers = testUtils.controlPanel;
var createView = testUtils.createView;
QUnit.module('fields', {}, function () {
@@ -1505,7 +1506,7 @@ QUnit.module('fields', {}, function () {
"second dialog should be closed");
assert.strictEqual($('.modal .o_data_row').length, 1,
"there should be one record in the one2many in the dialog");
- assert.notOk($('.modal .o_x2m_control_panel .o_cp_pager div').is(':visible'),
+ assert.containsNone($('.modal'), '.o_x2m_control_panel .o_pager',
'm2m pager should be hidden');
// click on 'Save & Close'
@@ -1756,16 +1757,14 @@ QUnit.module('fields', {}, function () {
// move to record 2, which has 3 related records (and shouldn't contain the
// related records of record 1 anymore). Two additional RPCs should have
// been done
- form.pager.next();
- await testUtils.nextTick();
+ await cpHelpers.pagerNext(form);
assert.strictEqual(count, 4, 'two RPCs should have been done');
assert.strictEqual(form.$('.o_kanban_record:not(".o_kanban_ghost")').length, 3,
'one2many kanban should contain 3 cards for record 2');
// move back to record 1, which should contain again its first 40 related
// records
- form.pager.previous();
- await testUtils.nextTick();
+ await cpHelpers.pagerPrevious(form);
assert.strictEqual(count, 6, 'two RPCs should have been done');
assert.strictEqual(form.$('.o_kanban_record:not(".o_kanban_ghost")').length, 40,
'one2many kanban should contain 40 cards for record 1');
@@ -1778,16 +1777,14 @@ QUnit.module('fields', {}, function () {
'one2many kanban should contain 2 cards for record 1 at page 2');
// move to record 2 again and check that everything is correctly updated
- form.pager.next();
- await testUtils.nextTick();
+ await cpHelpers.pagerNext(form);
assert.strictEqual(count, 9, 'two RPCs should have been done');
assert.strictEqual(form.$('.o_kanban_record:not(".o_kanban_ghost")').length, 3,
'one2many kanban should contain 3 cards for record 2');
// move back to record 1 and move to page 2 again: all data should have
// been correctly reloaded
- form.pager.previous();
- await testUtils.nextTick();
+ await cpHelpers.pagerPrevious(form);
assert.strictEqual(count, 11, 'two RPCs should have been done');
await testUtils.dom.click(form.$('.o_x2m_control_panel .o_pager_next'));
assert.strictEqual(count, 12, 'one RPC should have been done');
@@ -2565,7 +2562,7 @@ QUnit.module('fields', {}, function () {
await testUtils.dom.click(form.$('.o_field_x2many_list_row_add a'));
await testUtils.dom.click(form.$el);
- assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_cp_pager').text().trim(), '1-3 / 5',
+ assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_pager').text().trim(), '1-3 / 5',
"pager should display the correct total");
form.destroy();
});
@@ -2898,7 +2895,7 @@ QUnit.module('fields', {}, function () {
await testUtils.form.clickEdit(form);
await testUtils.dom.click(form.$('.o_field_x2many_list_row_add a'));
// the record currently being added should not count in the pager
- assert.isNotVisible(form.$('.o_field_widget[name=turtles] .o_cp_pager'));
+ assert.containsNone(form, '.o_field_widget[name=turtles] .o_pager');
form.destroy();
});
@@ -2931,8 +2928,8 @@ QUnit.module('fields', {}, function () {
// confirm the discard operation
await testUtils.dom.click($('.modal .modal-footer .btn-primary'));
- assert.isVisible(form.$('.o_field_widget[name=turtles] .o_cp_pager'));
- assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_cp_pager').text().trim(), '1-3 / 4',
+ assert.isVisible(form.$('.o_field_widget[name=turtles] .o_pager'));
+ assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_pager').text().trim(), '1-3 / 4',
"pager should display correct values");
form.destroy();
@@ -3001,13 +2998,13 @@ QUnit.module('fields', {}, function () {
// see a confirm dialog
await testUtils.dom.click(form.$('.o_field_widget[name=turtles] .o_pager_next'));
- assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_cp_pager').text().trim(), '1-3 / 4',
+ assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_pager').text().trim(), '1-3 / 4',
"pager should still display the correct total");
// click on cancel
await testUtils.dom.click($('.modal .modal-footer .btn-secondary'));
- assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_cp_pager').text().trim(), '1-3 / 4',
+ assert.strictEqual(form.$('.o_field_widget[name=turtles] .o_pager').text().trim(), '1-3 / 4',
"pager should again display the correct total");
assert.containsOnce(form, '.o_field_one2many input.o_field_invalid',
"there should be an invalid input in the one2many");
@@ -3048,7 +3045,7 @@ QUnit.module('fields', {}, function () {
await testUtils.dom.click($('.modal .modal-footer .btn-primary'));
assert.containsOnce(form, 'tr.o_data_row');
- assert.isNotVisible(form.$('.o_field_widget[name=turtles] .o_cp_pager'));
+ assert.containsNone(form, '.o_field_widget[name=turtles] .o_pager');
form.destroy();
});
@@ -3911,14 +3908,14 @@ QUnit.module('fields', {}, function () {
'</form>',
});
- assert.ok(!form.$('.o_x2m_control_panel .o_cp_pager div').is(':visible'),
+ assert.containsNone(form, '.o_x2m_control_panel .o_pager',
'o2m pager should be hidden');
// click to create a subrecord
await testUtils.dom.click(form.$('tbody td.o_field_x2many_list_row_add a'));
assert.containsOnce(form, 'tr.o_data_row');
- assert.ok(!form.$('.o_x2m_control_panel .o_cp_pager div').is(':visible'),
+ assert.containsNone(form, '.o_x2m_control_panel .o_pager',
'o2m pager should be hidden');
form.destroy();
});
diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js
index 11d67bd3752..47703a4ce1f 100644
--- a/addons/web/static/tests/fields/relational_fields_tests.js
+++ b/addons/web/static/tests/fields/relational_fields_tests.js
@@ -8,6 +8,7 @@ var RamStorage = require('web.RamStorage');
var relationalFields = require('web.relational_fields');
var testUtils = require('web.test_utils');
+const cpHelpers = testUtils.controlPanel;
var createView = testUtils.createView;
QUnit.module('fields', {}, function () {
@@ -153,24 +154,10 @@ QUnit.module('relational_fields', {
QUnit.test('search more pager is reset when doing a new search', async function (assert) {
assert.expect(6);
- for(var i = 10; i < 180; i++) {
- this.data.partner.records.push({
- id: i,
- display_name: "Partner " + i,
- });
- }
-
- async function stringToEvent ($element, string) {
- for (var i = 0; i < string.length; i++) {
- var keyAscii = string.charCodeAt(i);
- $element.val($element.val()+string[i]);
- $element.trigger($.Event('keyup', {which: keyAscii, keyCode:keyAscii}));
- await testUtils.nextTick();
- }
- $element.trigger($.Event('keyup', {which: $.ui.keyCode.ENTER, keyCode:$.ui.keyCode.ENTER}));
- await testUtils.nextTick();
- }
+ this.data.partner.records.push(
+ ...new Array(170).fill().map((_, i) => ({ id: i + 10, name: "Partner " + i }))
+ );
this.data.partner.fields.datetime.searchable = true;
var form = await createView({
View: FormView,
@@ -192,7 +179,6 @@ QUnit.module('relational_fields', {
await testUtils.form.clickEdit(form);
-
await testUtils.fields.many2one.clickOpenDropdown('trululu');
await testUtils.fields.many2one.clickItem('trululu','Search');
await testUtils.dom.click($('.modal .o_pager_next'));
@@ -201,7 +187,8 @@ QUnit.module('relational_fields', {
assert.strictEqual($('.o_pager_value').text(), "181-160", "should display the second page");
assert.strictEqual($('tr.o_data_row').length, 80, "should display 80 record");
- await stringToEvent($('.modal .o_searchview_input'), 'first');
+ await cpHelpers.editSearch('.modal', "first");
+ await cpHelpers.validateSearch('.modal');
assert.strictEqual($('.o_pager_limit').text(), "11", "there should be 1 record");
assert.strictEqual($('.o_pager_value').text(), "11-1", "should display the first page");
@@ -1708,8 +1695,8 @@ QUnit.module('relational_fields', {
});
await testUtils.fields.many2one.clickOpenDropdown('trululu');
await testUtils.fields.many2one.clickItem('trululu', 'Search');
- await testUtils.dom.click($('.modal .o_search_options .fa-bars'));
- await testUtils.dom.click($('.modal .o_search_options .o_group_by_menu a:contains(Bar)'));
+ await cpHelpers.toggleGroupByMenu('.modal');
+ await cpHelpers.toggleMenuItem('.modal', "Bar");
await testUtils.dom.click($('.modal .o_group_header:first'));
@@ -1977,7 +1964,7 @@ QUnit.module('relational_fields', {
await testUtils.form.clickSave(form);
- assert.strictEqual(form.el.querySelector('.o_field_many2manytags').innerText, 'new value');
+ assert.strictEqual(form.el.querySelector('.o_field_many2manytags').innerText.trim(), "new value");
form.destroy();
});
diff --git a/addons/web/static/tests/views/calendar_tests.js b/addons/web/static/tests/views/calendar_tests.js
index a58c857d49e..5865d4be80b 100644
--- a/addons/web/static/tests/views/calendar_tests.js
+++ b/addons/web/static/tests/views/calendar_tests.js
@@ -305,6 +305,8 @@ QUnit.module('Views', {
});
await actionManager.doAction(1);
+ await testUtils.nextTick();
+
// displays month mode by default
assert.strictEqual($('.o_control_panel .breadcrumb-item').text(),
'Meetings Test (Dec 11 – 17, 2016)', "should display the current week");
diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js
index 52e2e3354c5..00a73d9a6fd 100644
--- a/addons/web/static/tests/views/form_tests.js
+++ b/addons/web/static/tests/views/form_tests.js
@@ -16,6 +16,7 @@ var widgetRegistry = require('web.widget_registry');
var Widget = require('web.Widget');
var _t = core._t;
+const cpHelpers = testUtils.controlPanel;
var createView = testUtils.createView;
var createActionManager = testUtils.createActionManager;
@@ -213,7 +214,7 @@ QUnit.module('Views', {
bar: true,
foo: "blip",
int_field: 9,
- })
+ });
var form = await createView({
View: FormView,
viewOptions: { mode: 'edit' },
@@ -249,7 +250,7 @@ QUnit.module('Views', {
this.data.partner.records.push({
id: 6,
p: [1],
- })
+ });
var form = await createView({
View: FormView,
viewOptions: { mode: 'edit' },
@@ -1858,7 +1859,7 @@ QUnit.module('Views', {
form.destroy();
});
- QUnit.test('sidebar is hidden when switching to edit mode', async function (assert) {
+ QUnit.test('toolbar is hidden when switching to edit mode', async function (assert) {
assert.expect(3);
var form = await createView({
@@ -1870,15 +1871,19 @@ QUnit.module('Views', {
'<field name="foo"/>' +
'</sheet>' +
'</form>',
- viewOptions: {hasSidebar: true},
+ viewOptions: {hasActionMenus: true},
res_id: 1,
});
- assert.isVisible(form.sidebar);
+ assert.containsOnce(form, '.o_cp_action_menus');
+
await testUtils.form.clickEdit(form);
- assert.isNotVisible(form.sidebar);
+
+ assert.containsNone(form, '.o_cp_action_menus');
+
await testUtils.form.clickDiscard(form);
- assert.isVisible(form.sidebar);
+
+ assert.containsOnce(form, '.o_cp_action_menus');
form.destroy();
});
@@ -2013,14 +2018,14 @@ QUnit.module('Views', {
'<field name="foo"/>' +
'</form>',
res_id: 1,
- viewOptions: {hasSidebar: true},
+ viewOptions: {hasActionMenus: true},
});
assert.strictEqual(form.$('.o_control_panel .breadcrumb').text(), 'first record',
"should have the display name of the record as title");
- await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(form.sidebar.$('a:contains(Duplicate)'));
+ await cpHelpers.toggleActionMenu(form);
+ await cpHelpers.toggleMenuItem(form, "Duplicate");
assert.strictEqual(form.$('.o_control_panel .breadcrumb').text(), 'first record (copy)',
"should have duplicated the record");
@@ -2040,7 +2045,7 @@ QUnit.module('Views', {
'<field name="foo"/>' +
'</form>',
res_id: 1,
- viewOptions: {hasSidebar: true, context: {hey: 'hoy'}},
+ viewOptions: {hasActionMenus: true, context: {hey: 'hoy'}},
mockRPC: function (route, args) {
if (args.method === 'read') {
// should have 2 read, one for initial load, second for
@@ -2052,8 +2057,8 @@ QUnit.module('Views', {
},
});
- await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(form.sidebar.$('a:contains(Duplicate)'));
+ await cpHelpers.toggleActionMenu(form);
+ await cpHelpers.toggleMenuItem(form, "Duplicate");
form.destroy();
});
@@ -2069,12 +2074,12 @@ QUnit.module('Views', {
'<field name="foo"/>' +
'</form>',
res_id: 1,
- viewOptions: {hasSidebar: true},
+ viewOptions: {hasActionMenus: true},
});
assert.strictEqual(form.$('.o_control_panel .breadcrumb').text(), 'first record',
"should have the display name of the record as title");
- assert.containsNone(form.sidebar, 'a:contains(Duplicate)',
+ assert.containsNone(form, '.o_cp_action_menus a:contains(Duplicate)',
"should not contains a 'Duplicate' action");
form.destroy();
});
@@ -2603,14 +2608,14 @@ QUnit.module('Views', {
data: this.data,
arch: '<form string="Partners"><field name="foo"></field></form>',
res_id: 1,
- viewOptions: {hasSidebar: true},
+ viewOptions: {hasActionMenus: true},
});
await testUtils.form.clickEdit(form);
await testUtils.fields.editInput(form.$('input[name=foo]'), 'tralala');
await testUtils.form.clickSave(form);
- await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(form.sidebar.$('a:contains(Duplicate)'));
+ await cpHelpers.toggleActionMenu(form);
+ await cpHelpers.toggleMenuItem(form, "Duplicate");
assert.strictEqual(form.$('input[name=foo]').val(), 'tralala', 'input should contain ABC');
@@ -2643,8 +2648,8 @@ QUnit.module('Views', {
},
});
- assert.strictEqual(form.$('.o_pager_value').text(), '1', "pager value should be 1");
- assert.strictEqual(form.$('.o_pager_limit').text(), '2', "pager limit should be 2");
+ assert.strictEqual(cpHelpers.getPagerValue(form), '1', "pager value should be 1");
+ assert.strictEqual(cpHelpers.getPagerSize(form), '2', "pager limit should be 2");
// switch to edit mode
await testUtils.form.clickEdit(form);
@@ -2655,19 +2660,19 @@ QUnit.module('Views', {
assert.strictEqual(form.$('input').val(), 'new value', 'input should contain new value');
// click on the pager to switch to the next record and cancel the confirm request
- await testUtils.dom.click('.o_pager_next'); // click on next
+ await cpHelpers.pagerNext(form);
assert.containsOnce(document.body, '.modal', "a confirm modal should be displayed");
await testUtils.dom.click('.modal-footer .btn-secondary'); // click on cancel
assert.strictEqual(form.$('input[name=foo]').val(), 'new value',
"input should still contain new value");
- assert.strictEqual(form.$('.o_pager_value').text(), '1', "pager value should still be 1");
+ assert.strictEqual(cpHelpers.getPagerValue(form), '1', "pager value should still be 1");
// click on the pager to switch to the next record and confirm
- await testUtils.dom.click('.o_pager_next'); // click on next
+ await cpHelpers.pagerNext(form);
assert.containsOnce(document.body, '.modal', "a confirm modal should be displayed");
await testUtils.dom.click('.modal-footer .btn-primary'); // click on confirm
assert.strictEqual(form.$('input[name=foo]').val(), 'blip', "input should contain blip");
- assert.strictEqual(form.$('.o_pager_value').text(), '2', "pager value should be 2");
+ assert.strictEqual(cpHelpers.getPagerValue(form), '2', "pager value should be 2");
assert.strictEqual(nbWrite, 0, 'no write RPC should have been done');
form.destroy();
@@ -2690,7 +2695,8 @@ QUnit.module('Views', {
},
res_id: 1,
});
- assert.strictEqual(form.$('.o_pager_value').text(), '1', "pager value should be 1");
+
+ assert.strictEqual(cpHelpers.getPagerValue(form), '1', "pager value should be 1");
// switch to edit mode
await testUtils.form.clickEdit(form);
@@ -2704,10 +2710,10 @@ QUnit.module('Views', {
await testUtils.form.clickSave(form);
// click on the pager to switch to the next record and cancel the confirm request
- await testUtils.dom.click('.o_pager_next'); // click on next
+ await cpHelpers.pagerNext(form);
assert.containsNone(document.body, '.modal:visible',
"no confirm modal should be displayed");
- assert.strictEqual(form.$('.o_pager_value').text(), '2', "pager value should be 2");
+ assert.strictEqual(cpHelpers.getPagerValue(form), '2', "pager value should be 2");
assert.containsN(form, '.o_priority .fa-star-o', 2,
'priority widget should have been rendered with correct value');
@@ -2717,10 +2723,10 @@ QUnit.module('Views', {
assert.containsOnce(form, '.o_priority .fa-star',
'priority widget should have been updated');
- await testUtils.dom.click('.o_pager_next'); // click on next
- assert.containsNone(document.body, '.modal:visible',
+ await cpHelpers.pagerNext(form);
+ assert.containsNone(document.body, '.modal:visible',
"no confirm modal should be displayed");
- assert.strictEqual(form.$('.o_pager_value').text(), '1', "pager value should be 1");
+ assert.strictEqual(cpHelpers.getPagerValue(form), '1', "pager value should be 1");
// switch to edit mode
await testUtils.form.clickEdit(form);
@@ -2733,8 +2739,8 @@ QUnit.module('Views', {
await testUtils.form.clickDiscard(form);
assert.containsOnce(document.body, '.modal', "a confirm modal should be displayed");
await testUtils.dom.click('.modal-footer .btn-primary'); // click on confirm
- await testUtils.dom.click('.o_pager_next'); // click on next
- assert.strictEqual(form.$('.o_pager_value').text(), '2', "pager value should be 2");
+ await cpHelpers.pagerNext(form);
+ assert.strictEqual(cpHelpers.getPagerValue(form), '2', "pager value should be 2");
form.destroy();
});
@@ -2769,7 +2775,7 @@ QUnit.module('Views', {
assert.hasClass(form.$('.o_notebook .nav-link:eq(1)'), 'active');
// click on the pager to switch to the next record
- await testUtils.dom.click('.o_pager_next');
+ await cpHelpers.pagerNext(form);
assert.doesNotHaveClass(form.$('.o_notebook .nav-link:eq(0)'), 'active');
assert.hasClass(form.$('.o_notebook .nav-link:eq(1)'), 'active');
@@ -2793,20 +2799,22 @@ QUnit.module('Views', {
},
});
- assert.isVisible(form.pager);
- assert.strictEqual(form.pager.$('.o_pager_value').text(), "1",
+ assert.containsOnce(form, '.o_pager');
+ assert.strictEqual(cpHelpers.getPagerValue(form), "1",
"current pager value should be 1");
- assert.strictEqual(form.pager.$('.o_pager_limit').text(), "2",
+ assert.strictEqual(cpHelpers.getPagerSize(form), "2",
"current pager limit should be 1");
await testUtils.form.clickCreate(form);
- assert.isNotVisible(form.pager);
+
+ assert.containsNone(form, '.o_pager');
await testUtils.form.clickSave(form);
- assert.isVisible(form.pager);
- assert.strictEqual(form.pager.$('.o_pager_value').text(), "3",
+
+ assert.containsOnce(form, '.o_pager');
+ assert.strictEqual(cpHelpers.getPagerValue(form), "3",
"current pager value should be 3");
- assert.strictEqual(form.pager.$('.o_pager_limit').text(), "3",
+ assert.strictEqual(cpHelpers.getPagerSize(form), "3",
"current pager limit should be 3");
form.destroy();
@@ -2835,10 +2843,11 @@ QUnit.module('Views', {
});
assert.strictEqual(form.mode, 'readonly', 'form view should be in readonly mode');
- assert.strictEqual(form.pager.$('.o_pager_value').text(), "1", 'pager value should be 1');
- await testUtils.dom.click(form.pager.$('.o_pager_next'));
+ assert.strictEqual(cpHelpers.getPagerValue(form), "1", 'pager value should be 1');
+
+ await cpHelpers.pagerNext(form);
- assert.strictEqual(form.pager.$('.o_pager_value').text(), "2", 'pager value should be 2');
+ assert.strictEqual(cpHelpers.getPagerValue(form), "2", 'pager value should be 2');
assert.strictEqual(form.mode, 'readonly', 'form view should be in readonly mode');
assert.strictEqual(pushStateCount, 2, "should have triggered 2 push_state");
@@ -2935,28 +2944,28 @@ QUnit.module('Views', {
viewOptions: {
ids: [1, 2, 4],
index: 0,
- hasSidebar: true,
+ hasActionMenus: true,
},
res_id: 1,
});
- assert.strictEqual(form.pager.$('.o_pager_value').text(), "1", 'pager value should be 1');
- assert.strictEqual(form.pager.$('.o_pager_limit').text(), "3", 'pager limit should be 3');
+ assert.strictEqual(cpHelpers.getPagerValue(form), "1", 'pager value should be 1');
+ assert.strictEqual(cpHelpers.getPagerSize(form), "3", 'pager limit should be 3');
assert.strictEqual(form.$('span:contains(yop)').length, 1,
'should have a field with foo value for record 1');
assert.ok(!$('.modal:visible').length, 'no confirm modal should be displayed');
- // open sidebar and delete
- await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(form.sidebar.$('a:contains(Delete)'));
+ // open action menu and delete
+ await cpHelpers.toggleActionMenu(form);
+ await cpHelpers.toggleMenuItem(form, "Delete");
assert.ok($('.modal').length, 'a confirm modal should be displayed');
// confirm the delete
await testUtils.dom.click($('.modal-footer button.btn-primary'));
- assert.strictEqual(form.pager.$('.o_pager_value').text(), "1", 'pager value should be 1');
- assert.strictEqual(form.pager.$('.o_pager_limit').text(), "2", 'pager limit should be 2');
+ assert.strictEqual(cpHelpers.getPagerValue(form), "1", 'pager value should be 1');
+ assert.strictEqual(cpHelpers.getPagerSize(form), "2", 'pager limit should be 2');
assert.strictEqual(form.$('span:contains(blip)').length, 1,
'should have a field with foo value for record 2');
form.destroy();
@@ -2973,7 +2982,7 @@ QUnit.module('Views', {
viewOptions: {
ids: [1],
index: 0,
- hasSidebar: true,
+ hasActionMenus: true,
},
res_id: 1,
mockRPC: function (route, args) {
@@ -2982,9 +2991,8 @@ QUnit.module('Views', {
}
});
- // open sidebar, click on delete and confirm
- await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(form.sidebar.$('a:contains(Delete)'));
+ await cpHelpers.toggleActionMenu(form);
+ await cpHelpers.toggleMenuItem(form, "Delete");
await testUtils.mock.intercept(form, 'history_back', function () {
assert.step('history_back');
@@ -5209,13 +5217,13 @@ QUnit.module('Views', {
device: {size_class: size_class},
},
});
- }
+ };
var assertFormContainsNButtonsWithSizeClass = async function (size_class, n) {
var form = await createFormWithDeviceSizeClass(size_class);
assert.containsN(form, statButtonSelector, n, 'The form has the expected amount of buttons');
form.destroy();
- }
+ };
await assertFormContainsNButtonsWithSizeClass(0, 2);
await assertFormContainsNButtonsWithSizeClass(1, 2);
@@ -5510,7 +5518,7 @@ QUnit.module('Views', {
print: [],
},
viewOptions: {
- hasSidebar: true,
+ hasActionMenus: true,
},
mockRPC: function (route, args) {
if (route === '/web/action/load') {
@@ -5524,17 +5532,15 @@ QUnit.module('Views', {
},
});
- var $printMenu = form.$('.o_cp_sidebar .o_dropdown:contains(Print)');
- assert.isNotVisible($printMenu);
- var $actionMenu = form.$('.o_cp_sidebar .o_dropdown:contains(Action)');
- assert.isVisible($actionMenu);
+ assert.containsNone(form, '.o_cp_action_menus .o_dropdown:contains(Print)');
+ assert.containsOnce(form, '.o_cp_action_menus .o_dropdown:contains(Action)');
- testUtils.dom.click($actionMenu.find('button')); // open Action menu
- assert.strictEqual($actionMenu.find('.dropdown-item').length, 3,
- 'there should be 3 actions');
- var $customAction = $actionMenu.find('.dropdown-item:last');
- assert.strictEqual($customAction.text().trim(), 'Action partner',
+ await cpHelpers.toggleActionMenu(form);
+
+ assert.containsN(form, '.o_cp_action_menus .dropdown-item', 3, "there should be 3 actions");
+ assert.strictEqual(form.$('.o_cp_action_menus .dropdown-item:last').text().trim(), 'Action partner',
"the custom action should have 'Action partner' as name");
+
await testUtils.mock.intercept(form, 'do_action', function (event) {
var context = event.data.action.context.__contexts[1];
assert.strictEqual(context.active_id, 1,
@@ -5542,7 +5548,7 @@ QUnit.module('Views', {
assert.deepEqual(context.active_ids, [1],
"the active_ids should be an array with 1 inside.");
});
- await testUtils.dom.click($customAction);
+ await cpHelpers.toggleMenuItem(form, "Action partner");
form.destroy();
});
@@ -5687,14 +5693,16 @@ QUnit.module('Views', {
"first tab should be active");
// click on the pager to switch to the next record
- await testUtils.dom.click(form.pager.$('.o_pager_next'));
+ await cpHelpers.pagerNext(form);
+
assert.strictEqual(form.$('.o_notebook .nav-item:not(.o_invisible_modifier)').length, 1,
"only the second tab should be visible");
assert.hasClass(form.$('.o_notebook .nav-item:not(.o_invisible_modifier) .nav-link'),'active',
"the visible tab should be active");
// click on the pager to switch back to the previous record
- await testUtils.dom.click(form.pager.$('.o_pager_previous'));
+ await cpHelpers.pagerPrevious(form);
+
assert.strictEqual(form.$('.o_notebook .nav-item:not(.o_invisible_modifier)').length, 2,
"both tabs should be visible again");
assert.hasClass(form.$('.o_notebook .nav-link:nth(1)'),'active',
@@ -6205,24 +6213,22 @@ QUnit.module('Views', {
await testUtils.fields.editInput(form.$('input[name="foo"]'), "test");
await testUtils.form.clickSave(form);
- assert.containsOnce(form, '.o_form_view .alert > div',"should have a translation alert");
+ assert.containsOnce(form, '.o_form_view .alert > div', "should have a translation alert");
// click on the pager to switch to the next record
- await testUtils.dom.click(form.pager.$('.o_pager_next'));
- assert.strictEqual(form.$('.o_form_view .alert > div').length, 0,
- "should not have a translation alert");
+ await cpHelpers.pagerNext(form);
+ assert.containsNone(form, '.o_form_view .alert > div', "should not have a translation alert");
// click on the pager to switch back to the previous record
- await testUtils.dom.click(form.pager.$('.o_pager_previous'));
- assert.containsOnce(form, '.o_form_view .alert > div',"should have a translation alert");
+ await cpHelpers.pagerPrevious(form);
+ assert.containsOnce(form, '.o_form_view .alert > div', "should have a translation alert");
// remove translation alert by click X and check alert even after form reload
await testUtils.dom.click(form.$('.o_form_view .alert > .close'));
- assert.strictEqual(form.$('.o_form_view > .alert > div').length, 0,
- "should not have a translation alert");
+ assert.containsNone(form, '.o_form_view .alert > div', "should not have a translation alert");
+
await form.reload();
- assert.strictEqual(form.$('.o_form_view .alert > div').length, 0,
- "should not have a translation alert after reload");
+ assert.containsNone(form, '.o_form_view .alert > div', "should not have a translation alert after reload");
form.destroy();
_t.database.multi_lang = multi_lang;
@@ -7017,7 +7023,7 @@ QUnit.module('Views', {
'<field name="display_name"/>' +
'</form>',
res_id: 1,
- viewOptions: {hasSidebar: true},
+ viewOptions: {hasActionMenus: true},
mockRPC: function (route, args) {
var result = this._super.apply(this, arguments);
if (args.method === 'copy') {
@@ -7035,8 +7041,9 @@ QUnit.module('Views', {
});
// duplicate record 1
- await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(form.sidebar.$('a:contains(Duplicate)'));
+ await cpHelpers.toggleActionMenu(form);
+ await cpHelpers.toggleMenuItem(form, "Duplicate");
+
assert.containsOnce(form, '.o_form_editable',
"form should be in edit mode");
assert.strictEqual(form.$('.o_field_widget').val(), 'first record (copy)',
@@ -7044,8 +7051,8 @@ QUnit.module('Views', {
await testUtils.form.clickSave(form); // save duplicated record
// delete duplicated record
- await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(form.sidebar.$('a:contains(Delete)'));
+ await cpHelpers.toggleActionMenu(form);
+ await cpHelpers.toggleMenuItem(form, "Delete");
assert.strictEqual($('.modal').length, 1, "should have opened a confirm dialog");
await testUtils.dom.click($('.modal-footer .btn-primary'));
@@ -7320,7 +7327,7 @@ QUnit.module('Views', {
'</form>',
});
- var onFileLoadedEventName = form.$('.o_form_binary_form').attr('target')
+ var onFileLoadedEventName = form.$('.o_form_binary_form').attr('target');
// trigger _onFileLoaded function
$(window).trigger(onFileLoadedEventName, [{id: 5}, {id:2}]);
@@ -7629,7 +7636,7 @@ QUnit.module('Views', {
});
QUnit.test('do not change pager when discarding current record', async function (assert) {
- assert.expect(2);
+ assert.expect(4);
var form = await createView({
View: FormView,
@@ -7645,14 +7652,18 @@ QUnit.module('Views', {
res_id: 2,
});
- assert.strictEqual(form.pager.$('.o_pager_counter').text().trim(), '2 / 2',
+ assert.strictEqual(cpHelpers.getPagerValue(form), "2",
+ 'pager should indicate that we are on second record');
+ assert.strictEqual(cpHelpers.getPagerSize(form), "2",
'pager should indicate that we are on second record');
await testUtils.form.clickEdit(form);
await testUtils.form.clickDiscard(form);
- assert.strictEqual(form.pager.$('.o_pager_counter').text().trim(), '2 / 2',
- 'pager should not have changed');
+ assert.strictEqual(cpHelpers.getPagerValue(form), "2",
+ 'pager value should not have changed');
+ assert.strictEqual(cpHelpers.getPagerSize(form), "2",
+ 'pager limit should not have changed');
form.destroy();
});
@@ -7801,13 +7812,13 @@ QUnit.module('Views', {
},
res_id: 1,
viewOptions: {
- hasSidebar: true,
+ hasActionMenus: true,
},
});
core.bus.on('clear_cache', form, assert.step.bind(assert, 'clear_cache'));
- await testUtils.dom.click(form.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(form.sidebar.$('a:contains(Delete)'));
+ await cpHelpers.toggleActionMenu(form);
+ await cpHelpers.toggleMenuItem(form, "Delete");
await testUtils.dom.click($('.modal-footer .btn-primary'));
assert.verifySteps(['unlink', 'clear_cache']);
@@ -8166,7 +8177,7 @@ QUnit.module('Views', {
await testUtils.fields.many2one.clickOpenDropdown('trululu');
// switch to another record (should ask to discard changes, and reset the domain)
- await testUtils.dom.click(form.pager.$('.o_pager_next'));
+ await cpHelpers.pagerNext(form);
// discard changes by clicking on confirm in the dialog
await testUtils.dom.click($('.modal .modal-footer .btn-primary:first'));
diff --git a/addons/web/static/tests/views/graph_tests.js b/addons/web/static/tests/views/graph_tests.js
index d0cbe9d7a2e..05d490927ea 100644
--- a/addons/web/static/tests/views/graph_tests.js
+++ b/addons/web/static/tests/views/graph_tests.js
@@ -1,24 +1,26 @@
odoo.define('web.graph_view_tests', function (require) {
"use strict";
-var concurrency = require('web.concurrency');
-var controlPanelViewParameters = require('web.controlPanelViewParameters');
+var searchUtils = require('web.searchUtils');
var GraphView = require('web.GraphView');
var testUtils = require('web.test_utils');
+const cpHelpers = testUtils.controlPanel;
var createActionManager = testUtils.createActionManager;
var createView = testUtils.createView;
var patchDate = testUtils.mock.patchDate;
-var INTERVAL_OPTIONS = controlPanelViewParameters.INTERVAL_OPTIONS.map(o => o.optionId);
-var TIME_RANGE_OPTIONS = controlPanelViewParameters.TIME_RANGE_OPTIONS.map(o => o.optionId);
-var COMPARISON_TIME_RANGE_OPTIONS = controlPanelViewParameters.COMPARISON_TIME_RANGE_OPTIONS.map(o => o.optionId);
+const { INTERVAL_OPTIONS, TIME_RANGE_OPTIONS, COMPARISON_TIME_RANGE_OPTIONS } = searchUtils;
+
+var INTERVAL_OPTION_IDS = Object.keys(INTERVAL_OPTIONS);
+var TIME_RANGE_OPTION_IDS = Object.keys(TIME_RANGE_OPTIONS);
+var COMPARISON_TIME_RANGE_OPTION_IDS = Object.keys(COMPARISON_TIME_RANGE_OPTIONS);
var f = (a, b) => [].concat(...a.map(d => b.map(e => [].concat(d, e))));
var cartesian = (a, b, ...c) => (b ? cartesian(f(a, b), ...c) : a);
-var COMBINATIONS = cartesian(TIME_RANGE_OPTIONS, COMPARISON_TIME_RANGE_OPTIONS);
-var COMBINATIONS_WITH_DATE = cartesian(TIME_RANGE_OPTIONS, COMPARISON_TIME_RANGE_OPTIONS, INTERVAL_OPTIONS);
+var COMBINATIONS = cartesian(TIME_RANGE_OPTION_IDS, COMPARISON_TIME_RANGE_OPTION_IDS);
+var COMBINATIONS_WITH_DATE = cartesian(TIME_RANGE_OPTION_IDS, COMPARISON_TIME_RANGE_OPTION_IDS, INTERVAL_OPTION_IDS);
QUnit.assert.checkDatasets = function (graph, keys, expectedDatasets) {
keys = keys instanceof Array ? keys : [keys];
@@ -192,7 +194,7 @@ QUnit.module('Views', {
'groupby should not contain id field');
}
return this._super.apply(this, arguments);
- }
+ },
});
graph.destroy();
});
@@ -298,9 +300,9 @@ QUnit.module('Views', {
return this._super(route, args);
},
});
+ await cpHelpers.toggleMenu(graph, "Measures");
+ await cpHelpers.toggleMenuItem(graph, "Foo");
- testUtils.dom.click(graph.$buttons.find('.dropdown-toggle:contains(Measures)'));
- await testUtils.dom.click(graph.$buttons.find('.dropdown-item[data-field="foo"]'));
assert.checkLegend(graph, 'Foo');
assert.strictEqual(rpcCount, 2, "should have done 2 rpcs (2 readgroups)");
@@ -330,7 +332,7 @@ QUnit.module('Views', {
QUnit.test('no content helper (pie chart)', async function (assert) {
assert.expect(2);
- this.data.foo.records = []
+ this.data.foo.records = [];
var graph = await createView({
View: GraphView,
@@ -357,14 +359,11 @@ QUnit.module('Views', {
model: "foo",
data: this.data,
context: {
- timeRangeMenuData: {
- //Q3 2018
- timeRange: ['&', ["date", ">=", "2018-07-01"],["date", "<=", "2018-09-30"]],
- timeRangeDescription: 'This Quarter',
- //Q4 2018
- comparisonTimeRange: ['&', ["date", ">=", "2018-10-01"],["date", "<=", "2018-12-31"]],
- comparisonTimeRangeDescription: 'Previous Period',
- },
+ time_ranges: {
+ field: 'date',
+ range: 'this_quarter',
+ comparisonRange: 'previous_period',
+ }
},
arch: '<graph type="pie">' +
'<field name="product_id"/>' +
@@ -443,8 +442,9 @@ QUnit.module('Views', {
}
}, "context should be correct");
- testUtils.dom.click(graph.$buttons.find('.dropdown-toggle:contains(Measures)'));
- await testUtils.dom.click(graph.$buttons.find('.dropdown-item[data-field="foo"]'));
+ await cpHelpers.toggleMenu(graph, "Measures");
+ await cpHelpers.toggleMenuItem(graph, "Foo");
+
assert.deepEqual(graph.getOwnedQueryParams(), {
context: {
graph_mode: 'bar',
@@ -567,7 +567,7 @@ QUnit.module('Views', {
assert.hasClass(graph.$buttons.find('button[data-mode="line"]'),'active',
'line chart button should be active');
// check groupby values ('Undefined' is rejected in line chart) are in labels
- assert.checkLabels(graph, [['red'], ['black']])
+ assert.checkLabels(graph, [['red'], ['black']]);
graph.destroy();
});
@@ -687,10 +687,11 @@ QUnit.module('Views', {
additionalMeasures: ['product_id'],
},
});
+
// need to set the measure this way because it cannot be set in the
// arch.
- await testUtils.dom.click(graph.$buttons.find('.dropdown-toggle:contains(Measures)'));
- await testUtils.dom.click(graph.$buttons.find('.dropdown-item[data-field="product_id"]'));
+ await cpHelpers.toggleMenu(graph, "Measures");
+ await cpHelpers.toggleMenuItem(graph, "Product");
assert.checkLabels(graph, [['xphone'], ['xpad']]);
assert.checkLegend(graph, 'Product');
@@ -729,8 +730,10 @@ QUnit.module('Views', {
additionalMeasures: ['product_id'],
},
});
- assert.ok(graph.measures.product_id,
+
+ assert.ok(graph.measures.find(m => m.fieldName === 'product_id'),
"should have product_id as measure");
+
graph.destroy();
});
@@ -766,9 +769,10 @@ QUnit.module('Views', {
'</graph>',
});
- assert.strictEqual(graph.$buttons.find('.o_graph_measures_list .dropdown-item:first').data('field'), 'bouh',
+ await cpHelpers.toggleMenu(graph, "Measures");
+ assert.strictEqual(graph.$buttons.find('.o_graph_measures_list .dropdown-item:first').text(), 'bouh',
"Bouh should be the first measure");
- assert.strictEqual(graph.$buttons.find('.o_graph_measures_list .dropdown-item:last').data('field'), '__count__',
+ assert.strictEqual(graph.$buttons.find('.o_graph_measures_list .dropdown-item:last').text(), 'Count',
"Count should be the last measure");
graph.destroy();
@@ -788,7 +792,7 @@ QUnit.module('Views', {
});
function _indexOf (label) {
- return graph.renderer._indexOf(graph.renderer.chart.data.labels, label)
+ return graph.renderer._indexOf(graph.renderer.chart.data.labels, label);
}
assert.strictEqual(_indexOf(['Undefined']), -1);
@@ -816,7 +820,7 @@ QUnit.module('Views', {
});
function _indexOf (label) {
- return graph.renderer._indexOf(graph.renderer.chart.data.labels, label)
+ return graph.renderer._indexOf(graph.renderer.chart.data.labels, label);
}
assert.strictEqual(_indexOf(['Undefined']), -1);
@@ -825,7 +829,7 @@ QUnit.module('Views', {
assert.ok(_indexOf(['Undefined']) >= 0);
await testUtils.dom.click(graph.$buttons.find('.o_graph_button[data-mode=pie]'));
- var labels = graph.renderer.chart.data.labels
+ var labels = graph.renderer.chart.data.labels;
assert.ok(labels.filter(label => /Undefined/.test(label.join(''))).length >= 1);
// Undefined should not appear after switching back to line chart
@@ -908,7 +912,7 @@ QUnit.module('Views', {
groupBy: ['product_id', 'color_id'],
});
- assert.checkLabels(graph, [['xphone'], ['xpad']])
+ assert.checkLabels(graph, [['xphone'], ['xpad']]);
assert.checkLegend(graph, ['Undefined', 'red']);
assert.checkDatasets(graph, ['label', 'data'], [
{
@@ -922,7 +926,7 @@ QUnit.module('Views', {
]);
await testUtils.dom.click(graph.$('.o_graph_button[data-mode=line]'));
- assert.checkLabels(graph, [['xphone'], ['xpad']])
+ assert.checkLabels(graph, [['xphone'], ['xpad']]);
assert.checkLegend(graph, ['Undefined', 'red']);
assert.checkDatasets(graph, ['label', 'data'], [
{
@@ -936,7 +940,7 @@ QUnit.module('Views', {
]);
await testUtils.dom.click(graph.$('.o_graph_button[data-mode=pie]'));
- assert.checkLabels(graph, [['xphone', 'Undefined'], ['xphone', 'red'], ['xpad', 'Undefined']])
+ assert.checkLabels(graph, [['xphone', 'Undefined'], ['xphone', 'red'], ['xpad', 'Undefined']]);
assert.checkLegend(graph, ['xphone/Undefined', 'xphone/red', 'xpad/Undefined']);
assert.checkDatasets(graph, ['label', 'data'], {
label: '',
@@ -1015,7 +1019,7 @@ QUnit.module('Views', {
if (exhaustiveTest) {
i++;
} else {
- i += Math.floor(1 + Math.random() * 20)
+ i += Math.floor(1 + Math.random() * 20);
}
yield combination;
}
@@ -1033,7 +1037,7 @@ QUnit.module('Views', {
self.combinationsToCheck[combination].errorMessage
);
} else {
- assert.checkLabels(graph, self.combinationsToCheck[combination].labels)
+ assert.checkLabels(graph, self.combinationsToCheck[combination].labels);
assert.checkLegend(graph, self.combinationsToCheck[combination].legend);
assert.checkDatasets(graph, ['label', 'data'], self.combinationsToCheck[combination].datasets);
}
@@ -1041,76 +1045,62 @@ QUnit.module('Views', {
}
};
+ const GROUPBY_NAMES = ['Date', 'Bar', 'Product', 'Color'];
+
// time range menu is assumed to be closed
this.selectTimeRanges = async function (timeRangeOption, comparisonTimeRangeOption) {
comparisonTimeRangeOption = comparisonTimeRangeOption || 'previous_period';
- // open time range menu
- await testUtils.dom.click($('.o_control_panel .o_time_range_menu_button'));
- // select range
- await testUtils.fields.editInput($('.o_control_panel .o_time_range_selector'), timeRangeOption);
- // check checkbox 'Compare To'
- if (!$('.o_control_panel .o_time_range_menu .o_comparison_checkbox').prop('checked')) {
- await testUtils.dom.click($('.o_control_panel .o_time_range_menu .o_comparison_checkbox'));
+ await cpHelpers.toggleTimeRangeMenu(document);
+ await cpHelpers.selectRange(document, timeRangeOption);
+ if (!document.querySelector('div.o_time_range_section input').checked) {
+ await cpHelpers.toggleTimeRangeMenuBox(document);
}
- // select 'Previous period' or 'Previous year' acording to comparisonTimeRangeOption
- await testUtils.fields.editInput($('.o_control_panel .o_comparison_time_range_selector'), comparisonTimeRangeOption);
- // Click on 'Apply' button
- await testUtils.dom.click($('.o_control_panel .o_time_range_menu .o_apply_range'));
+ await cpHelpers.selectComparisonRange(document, comparisonTimeRangeOption);
+ await cpHelpers.applyTimeRange(document);
+ await cpHelpers.toggleTimeRangeMenu(document);
};
// groupby menu is assumed to be closed
this.selectDateIntervalOption = async function (intervalOption) {
- const self = this;
intervalOption = intervalOption || 'month';
+ const optionIndex = INTERVAL_OPTION_IDS.indexOf(intervalOption);
- // open group by menu
- await testUtils.dom.click($('.o_control_panel .o_dropdown span.fa-bars'));
-
+ await cpHelpers.toggleGroupByMenu(document);
let wasSelected = false;
if (this.keepFirst) {
- if ($('.o_control_panel .o_group_by_menu .o_menu_item:contains(Product) a').hasClass('selected')) {
+ if (cpHelpers.isItemSelected(document, 2)) {
wasSelected = true;
- await testUtils.dom.click($('.o_control_panel .o_group_by_menu .o_menu_item:contains(Product)'));
+ await cpHelpers.toggleMenuItem(document, 2);
}
}
-
- // open option submenu
- await testUtils.dom.click($('.o_control_panel .o_group_by_menu .o_menu_item:contains("Date")'));
- // check interval option if not already selected
- if (!$('.o_control_panel .o_group_by_menu .o_item_option[data-option_id="' + intervalOption + '"] a').hasClass('selected')) {
- await testUtils.dom.click($('.o_control_panel .o_group_by_menu .o_item_option[data-option_id="' + intervalOption + '"]'));
+ await cpHelpers.toggleMenuItem(document, 0);
+ if (!cpHelpers.isOptionSelected(document, 0, optionIndex)) {
+ await cpHelpers.toggleMenuItemOption(document, 0, optionIndex);
}
- await INTERVAL_OPTIONS.filter(oId => oId !== intervalOption).forEach(async function(oId) {
- if ($('.o_control_panel .o_group_by_menu .o_item_option[data-option_id="' + oId + '"] a').hasClass('selected')) {
- await testUtils.dom.click($('.o_control_panel .o_group_by_menu .o_item_option[data-option_id="' + oId + '"]'));
+ for (let i = 0; i < INTERVAL_OPTION_IDS.length; i++) {
+ const oId = INTERVAL_OPTION_IDS[i];
+ if (oId !== intervalOption && cpHelpers.isOptionSelected(document, 0, i)) {
+ await cpHelpers.toggleMenuItemOption(document, 0, i);
}
- });
+ }
if (this.keepFirst) {
- if (wasSelected && !$('.o_control_panel .o_group_by_menu .o_menu_item:contains(Product) a').hasClass('selected')) {
- await testUtils.dom.click($('.o_control_panel .o_group_by_menu .o_menu_item:contains(Product)'));
+ if (wasSelected && !cpHelpers.isItemSelected(document, 2)) {
+ await cpHelpers.toggleMenuItem(document, 2);
}
}
+ await cpHelpers.toggleGroupByMenu(document);
- // close group by menu
- await testUtils.dom.click($('.o_control_panel .o_dropdown span.fa-bars'));
};
// groupby menu is assumed to be closed
this.selectGroupBy = async function (groupByName) {
- // open group by menu
- await testUtils.dom.click($('.o_control_panel .o_dropdown span.fa-bars'));
- // check groupBy if not already selected
- if (!$('.o_control_panel .o_group_by_menu .o_menu_item:contains(' + groupByName + ') a').hasClass('selected')) {
- await testUtils.dom.click($('.o_control_panel .o_group_by_menu .o_menu_item:contains(' + groupByName + ')'));
+ await cpHelpers.toggleGroupByMenu(document);
+ const index = GROUPBY_NAMES.indexOf(groupByName);
+ if (!cpHelpers.isItemSelected(document, index)) {
+ await cpHelpers.toggleMenuItem(document, index);
}
- // close group by menu
- await testUtils.dom.click($('.o_control_panel .o_dropdown span.fa-bars'));
- };
- // groupby menu is assumed to be closed
- this.unselectGroupBy = async function (groupByName) {
- // check groupBy if already selected
-
+ await cpHelpers.toggleGroupByMenu(document);
};
this.setConfig = async function (combination) {
@@ -1121,7 +1111,7 @@ QUnit.module('Views', {
};
this.setMode = async function (mode) {
- await testUtils.dom.click($('.o_control_panel .o_graph_button[data-mode=' + mode + ']'));
+ await testUtils.dom.click($(`.o_control_panel .o_graph_button[data-mode="${mode}"]`));
};
// // create an action manager to test the interactions with the search view
@@ -1148,7 +1138,7 @@ QUnit.module('Views', {
graph: {
additionalMeasures: ['product_id'],
}
- }
+ },
});
},
afterEach: function () {
diff --git a/addons/web/static/tests/views/kanban_tests.js b/addons/web/static/tests/views/kanban_tests.js
index 47c3862ba8f..9adc2f00069 100644
--- a/addons/web/static/tests/views/kanban_tests.js
+++ b/addons/web/static/tests/views/kanban_tests.js
@@ -14,6 +14,7 @@ var widgetRegistry = require('web.widget_registry');
var makeTestPromise = testUtils.makeTestPromise;
var nextTick = testUtils.nextTick;
+const cpHelpers = testUtils.controlPanel;
var createView = testUtils.createView;
QUnit.module('Views', {
@@ -345,10 +346,9 @@ QUnit.module('Views', {
'</t></templates></kanban>',
groupBy: ['bar'],
});
- await kanban.renderPager();
- assert.isNotVisible(kanban.pager.$el,
- "pager should be hidden in grouped kanban");
+ assert.containsNone(kanban, '.o_pager');
+
kanban.destroy();
});
@@ -369,9 +369,8 @@ QUnit.module('Views', {
},
});
- assert.isVisible(kanban.pager.$el,
- "pager should be visible in ungrouped kanban");
- assert.strictEqual(kanban.pager.state.size, 4, "pager's size should be 4");
+ assert.containsOnce(kanban, '.o_pager');
+ assert.strictEqual(cpHelpers.getPagerSize(kanban), "4", "pager's size should be 4");
kanban.destroy();
});
@@ -395,8 +394,8 @@ QUnit.module('Views', {
},
});
- assert.strictEqual(kanban.pager.state.limit, 2, "pager's limit should be 2");
- assert.strictEqual(kanban.pager.state.size, 4, "pager's size should be 4");
+ assert.strictEqual(cpHelpers.getPagerValue(kanban), "1-2", "pager's limit should be 2");
+ assert.strictEqual(cpHelpers.getPagerSize(kanban), "4", "pager's size should be 4");
kanban.destroy();
});
@@ -421,8 +420,8 @@ QUnit.module('Views', {
},
});
- assert.strictEqual(kanban.pager.state.limit, 3, "pager's limit should be 3");
- assert.strictEqual(kanban.pager.state.size, 4, "pager's size should be 4");
+ assert.strictEqual(cpHelpers.getPagerValue(kanban), "1-3", "pager's limit should be 3");
+ assert.strictEqual(cpHelpers.getPagerSize(kanban), "4", "pager's size should be 4");
kanban.destroy();
});
@@ -577,7 +576,7 @@ QUnit.module('Views', {
},
});
- assert.containsOnce(kanban, '.o_cp_controller', 'should have one control panel');
+ assert.containsOnce(kanban, '.o_control_panel', 'should have one control panel');
assert.containsOnce(kanban, '.o_kanban_group:first .o_kanban_record',
"first column should contain one record");
@@ -589,7 +588,7 @@ QUnit.module('Views', {
"should have a quick create element in the first column");
assert.strictEqual($quickCreate.find('.o_form_view.o_xxs_form_view').length, 1,
"should have rendered an XXS form view");
- assert.containsOnce(kanban, '.o_cp_controller', 'should not have instantiated an extra control panel');
+ assert.containsOnce(kanban, '.o_control_panel', 'should not have instantiated an extra control panel');
assert.strictEqual($quickCreate.find('input').length, 2,
"should have two inputs");
assert.strictEqual($quickCreate.find('.o_field_widget').length, 3,
@@ -1160,7 +1159,7 @@ QUnit.module('Views', {
assert.step('onchange');
if (shouldDelayOnchange) {
return Promise.resolve(prom).then(function () {
- return result
+ return result;
});
}
}
@@ -1255,7 +1254,7 @@ QUnit.module('Views', {
assert.step('onchange');
if (shouldDelayOnchange) {
return Promise.resolve(prom).then(function () {
- return result
+ return result;
});
}
}
@@ -4836,7 +4835,7 @@ QUnit.module('Views', {
'</t></templates>' +
'</kanban>',
mockRPC: function (route, args) {
- assert.step(route)
+ assert.step(route);
return this._super(route, args);
},
});
@@ -4971,12 +4970,12 @@ QUnit.module('Views', {
mockRPC: function (route, args) {
if (route === '/web/dataset/call_kw/partner/action_archive') {
var partnerIDS = args.args[0];
- var records = this.data.partner.records
+ var records = this.data.partner.records;
_.each(partnerIDS, function(partnerID) {
_.find(records, function (record) {
return record.id === partnerID;
}).active = false;
- })
+ });
this.data.partner.records[0].active;
return Promise.resolve();
}
diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js
index 19648bfb44b..b5ae51af648 100644
--- a/addons/web/static/tests/views/list_tests.js
+++ b/addons/web/static/tests/views/list_tests.js
@@ -15,11 +15,12 @@ var testUtils = require('web.test_utils');
var widgetRegistry = require('web.widget_registry');
var Widget = require('web.Widget');
+
var _t = core._t;
+const cpHelpers = testUtils.controlPanel;
var createActionManager = testUtils.createActionManager;
var createView = testUtils.createView;
-
QUnit.module('Views', {
beforeEach: function () {
this.data = {
@@ -178,20 +179,26 @@ QUnit.module('Views', {
QUnit.test('list with delete="0"', async function (assert) {
assert.expect(4);
- var list = await createView({
+ const list = await createView({
View: ListView,
model: 'foo',
data: this.data,
- viewOptions: {hasSidebar: true},
+ viewOptions: {hasActionMenus: true},
arch: '<tree delete="0"><field name="foo"/></tree>',
});
- assert.isNotVisible(list.sidebar.$el, 'sidebar should be invisible');
+
+ assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
assert.ok(list.$('tbody td.o_list_record_selector').length, 'should have at least one record');
await testUtils.dom.click(list.$('tbody td.o_list_record_selector:first input'));
- assert.isVisible(list.sidebar.$el, 'sidebar should be visible');
- assert.notOk(list.sidebar.$('a:contains(Delete)').length, 'sidebar should not have Delete button');
+ assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
+ await cpHelpers.toggleActionMenu(list);
+ assert.deepEqual(
+ cpHelpers.getMenuItemTexts(list),
+ ['Export'],
+ 'action menu should not have Delete button'
+ );
list.destroy();
});
@@ -203,7 +210,7 @@ QUnit.module('Views', {
View: ListView,
model: 'foo',
data: this.data,
- viewOptions: {hasSidebar: true},
+ viewOptions: {hasActionMenus: true},
arch: '<tree editable="top" edit="0"><field name="foo"/></tree>',
});
@@ -762,33 +769,31 @@ QUnit.module('Views', {
}
return this._super.apply(this,arguments);
},
- intercepts: {
- load_filters: function (event) {
- return Promise.resolve([
- {
- context: "{}",
- domain: "[]",
- id: 7,
- is_default: true,
- name: "My favorite",
- sort: "[\"date asc\", \"foo desc\"]",
- user_id: [2, "Mitchell Admin"],
- }, {
- context: "{}",
- domain: "[]",
- id: 8,
- is_default: false,
- name: "My second favorite",
- sort: "[\"date desc\", \"foo asc\"]",
- user_id: [2, "Mitchell Admin"],
- }
- ]).then(event.data.on_success);
- },
- },
+ favoriteFilters : [
+ {
+ context: "{}",
+ domain: "[]",
+ id: 7,
+ is_default: true,
+ name: "My favorite",
+ sort: "[\"date asc\", \"foo desc\"]",
+ user_id: [2, "Mitchell Admin"],
+ }, {
+ context: "{}",
+ domain: "[]",
+ id: 8,
+ is_default: false,
+ name: "My second favorite",
+ sort: "[\"date desc\", \"foo asc\"]",
+ user_id: [2, "Mitchell Admin"],
+ }
+ ]
});
- await testUtils.dom.click(list.$('.o_control_panel .o_search_options button.o_favorites_menu_button'));
- await testUtils.dom.click(list.$('.o_control_panel .o_search_options .o_favorites_menu .o_menu_item').eq(1));
+
+ await cpHelpers.toggleFavoriteMenu(list);
+ await cpHelpers.toggleMenuItem(list, "My second favorite");
+
list.destroy();
});
@@ -843,9 +848,10 @@ QUnit.module('Views', {
assert.ok("list view should trigger 'open_record' event");
});
- testUtils.dom.click(list.$('tr td:not(.o_list_record_selector)').first());
+ await testUtils.dom.click(list.$('tr td:not(.o_list_record_selector)').first());
list.update({groupBy: ['foo']});
await testUtils.nextTick();
+
assert.containsN(list, 'tr.o_group_header', 3, "list should be grouped");
await testUtils.dom.click(list.$('th.o_group_name').first());
@@ -1007,11 +1013,13 @@ QUnit.module('Views', {
domain: [['foo', '=', 'yop']],
});
+
assert.containsN(list, 'tbody tr', 4,
"list should contain 4 rows");
assert.containsOnce(list, '.o_data_row',
"list should contain one record (and thus 3 empty rows)");
- assert.strictEqual(list.pager.$('.o_pager_value').text(), '1-1',
+
+ assert.strictEqual(cpHelpers.getPagerValue(list), '1-1',
"pager should be correct");
await testUtils.dom.click(list.$buttons.find('.o_list_button_add'));
@@ -1020,7 +1028,7 @@ QUnit.module('Views', {
"list should still contain 4 rows");
assert.containsN(list, '.o_data_row', 2,
"list should contain two record (and thus 2 empty rows)");
- assert.strictEqual(list.pager.$('.o_pager_value').text(), '1-2',
+ assert.strictEqual(cpHelpers.getPagerValue(list), '1-2',
"pager should be correct");
await testUtils.dom.click(list.$buttons.find('.o_list_button_discard'));
@@ -1029,7 +1037,7 @@ QUnit.module('Views', {
"list should still contain 4 rows");
assert.containsOnce(list, '.o_data_row',
"list should contain one record (and thus 3 empty rows)");
- assert.strictEqual(list.pager.$('.o_pager_value').text(), '1-1',
+ assert.strictEqual(cpHelpers.getPagerValue(list), '1-1',
"pager should be correct");
assert.verifySteps(['destroy'],
"should have destroyed the widget of the removed line");
@@ -1285,32 +1293,32 @@ QUnit.module('Views', {
model: 'foo',
data: this.data,
groupBy: ['foo'],
- viewOptions: {hasSidebar: true},
+ viewOptions: {hasActionMenus: true},
arch: '<tree>' +
'<field name="foo"/>' +
'<field name="int_field" sum="Sum"/>' +
'</tree>',
});
- assert.isNotVisible(list.sidebar);
+ assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
// open blip grouping and check all lines
await testUtils.dom.click(list.$('.o_group_header:contains("blip (2)")'));
await testUtils.dom.click(list.$('.o_data_row:first input'));
- assert.isVisible(list.sidebar);
+ assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
// open yop grouping and verify blip are still checked
await testUtils.dom.click(list.$('.o_group_header:contains("yop (1)")'));
assert.containsOnce(list, '.o_data_row input:checked',
"opening a grouping does not uncheck others");
- assert.isVisible(list.sidebar);
+ assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
// close and open blip grouping and verify blip are unchecked
await testUtils.dom.click(list.$('.o_group_header:contains("blip (2)")'));
await testUtils.dom.click(list.$('.o_group_header:contains("blip (2)")'));
assert.containsNone(list, '.o_data_row input:checked',
"opening and closing a grouping uncheck its elements");
- assert.isNotVisible(list.sidebar);
+ assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
list.destroy();
});
@@ -1599,10 +1607,9 @@ QUnit.module('Views', {
limit: 2,
},
});
-
var widthPage1 = list.$(`th[data-name=foo]`)[0].offsetWidth;
- await testUtils.dom.click(list.$('.o_pager_next'));
+ await cpHelpers.pagerNext(list);
var widthPage2 = list.$(`th[data-name=foo]`)[0].offsetWidth;
assert.ok(widthPage1 > widthPage2,
@@ -2477,19 +2484,20 @@ QUnit.module('Views', {
View: ListView,
model: 'foo',
data: this.data,
- viewOptions: {hasSidebar: true},
+ viewOptions: {hasActionMenus: true},
arch: '<tree><field name="foo"/></tree>',
});
- assert.isNotVisible(list.sidebar.$el, 'sidebar should be invisible');
+
+ assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
assert.containsN(list, 'tbody td.o_list_record_selector', 4, "should have 4 records");
await testUtils.dom.click(list.$('tbody td.o_list_record_selector:first input'));
- assert.isVisible(list.sidebar.$el, 'sidebar should be visible');
+ assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
- await testUtils.dom.click(list.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(list.sidebar.$('a:contains(Delete)'));
+ await cpHelpers.toggleActionMenu(list);
+ await cpHelpers.toggleMenuItem(list, "Delete");
assert.hasClass($('body'),'modal-open', 'body should have modal-open clsss');
await testUtils.dom.click($('body .modal button span:contains(Ok)'));
@@ -2508,7 +2516,7 @@ QUnit.module('Views', {
View: ListView,
model: 'foo',
data: this.data,
- viewOptions: {hasSidebar: true},
+ viewOptions: {hasActionMenus: true},
arch: '<tree><field name="foo"/></tree>',
mockRPC: function (route) {
assert.step(route);
@@ -2520,22 +2528,23 @@ QUnit.module('Views', {
},
});
- assert.isNotVisible(list.sidebar.$el, 'sidebar should be invisible');
+
+ assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
assert.containsN(list, 'tbody td.o_list_record_selector', 4, "should have 4 records");
await testUtils.dom.click(list.$('tbody td.o_list_record_selector:first input'));
- assert.isVisible(list.sidebar.$el, 'sidebar should be visible');
+ assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
assert.verifySteps(['/web/dataset/search_read']);
- await testUtils.dom.click(list.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(list.sidebar.$('a:contains(Archive)'));
+ await cpHelpers.toggleActionMenu(list);
+ await cpHelpers.toggleMenuItem(list, "Archive");
assert.strictEqual($('.modal').length, 1, 'a confirm modal should be displayed');
await testUtils.dom.click($('.modal-footer .btn-secondary'));
assert.containsN(list, 'tbody td.o_list_record_selector', 4, "still should have 4 records");
- await testUtils.dom.click(list.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(list.sidebar.$('a:contains(Archive)'));
+ await cpHelpers.toggleActionMenu(list);
+ await cpHelpers.toggleMenuItem(list, "Archive");
assert.strictEqual($('.modal').length, 1, 'a confirm modal should be displayed');
await testUtils.dom.click($('.modal-footer .btn-primary'));
assert.containsN(list, 'tbody td.o_list_record_selector', 3, "should have 3 records");
@@ -2559,10 +2568,10 @@ QUnit.module('Views', {
},
});
- assert.isVisible(list.pager.$el, "pager should be visible");
- assert.strictEqual(list.pager.state.size, 4, "pager's size should be 4");
+ assert.containsOnce(list.el, 'div.o_control_panel .o_cp_pager');
+ assert.strictEqual(cpHelpers.getPagerSize(list), "4", "pager's size should be 4");
await list.update({ groupBy: ['bar']});
- assert.strictEqual(list.pager.state.size, 2, "pager's size should be 2");
+ assert.strictEqual(cpHelpers.getPagerSize(list), "2", "pager's size should be 2");
list.destroy();
});
@@ -2803,8 +2812,7 @@ QUnit.module('Views', {
res_id: 1,
});
- // Change page
- await testUtils.dom.click(form.$('.o_field_widget[name=o2m] .o_pager_next'));
+ await cpHelpers.pagerNext('.o_field_widget[name=o2m]');
assert.strictEqual(form.$('tbody tr:first').text(), 'Value 44',
"record 44 should be first");
assert.strictEqual(form.$('tbody tr:eq(4)').text(), 'Value 48',
@@ -3819,23 +3827,23 @@ QUnit.module('Views', {
limit: 3,
},
});
-
var headerHeight = list.$('.o_group_header').css('height');
// basic rendering checks
await testUtils.dom.click(list.$('.o_group_header'));
assert.strictEqual(list.$('.o_group_header').css('height'), headerHeight,
"height of group header shouldn't have changed");
- assert.hasClass(list.$('.o_group_header th:eq(1) > div'), 'o_pager',
+ assert.hasClass(list.$('.o_group_header th:eq(1) > nav'), 'o_pager',
"last cell of open group header should have classname 'o_pager'");
- assert.strictEqual(list.$('.o_group_header .o_pager_value').text(), '1-3',
+
+ assert.strictEqual(cpHelpers.getPagerValue('.o_group_header'), '1-3',
"pager's value should be correct");
assert.containsN(list, '.o_data_row', 3,
"open group should display 3 records");
// go to next page
- await testUtils.dom.click(list.$('.o_group_header .o_pager_next'));
- assert.strictEqual(list.$('.o_group_header .o_pager_value').text(), '4-4',
+ await cpHelpers.pagerNext('.o_group_header');
+ assert.strictEqual(cpHelpers.getPagerValue('.o_group_header'), '4-4',
"pager's value should be correct");
assert.containsOnce(list, '.o_data_row',
"open group should display 1 record");
@@ -4109,14 +4117,14 @@ QUnit.module('Views', {
"3rd row should be selected");
// press enter in input
- await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
+ await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input[name="foo"]'), 'enter');
assert.hasClass(list.$('tr.o_data_row:eq(3)'),'o_selected_row',
"4rd row should be selected");
assert.doesNotHaveClass(list.$('tr.o_data_row:eq(2)'), 'o_selected_row',
"3rd row should no longer be selected");
// press enter on last row
- await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
+ await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input[name="foo"]'), 'enter');
assert.containsN(list, 'tr.o_data_row', 5, "should have created a 5th row");
assert.verifySteps(['/web/dataset/search_read', '/web/dataset/call_kw/foo/default_get']);
@@ -4220,7 +4228,7 @@ QUnit.module('Views', {
});
QUnit.test('display toolbar', async function (assert) {
- assert.expect(6);
+ assert.expect(2);
var list = await createView({
View: ListView,
@@ -4237,31 +4245,22 @@ QUnit.module('Views', {
print: [],
},
viewOptions: {
- hasSidebar: true,
+ hasActionMenus: true,
},
});
- var $printMenu = list.$('.o_cp_sidebar .o_dropdown:contains(Print)');
- assert.isNotVisible($printMenu);
- var $actionMenu = list.$('.o_cp_sidebar .o_dropdown:contains(Action)');
- assert.isNotVisible($actionMenu);
- testUtils.dom.click(list.$('.o_list_record_selector:first input'));
+ assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
- assert.isNotVisible($printMenu);
- assert.isVisible($actionMenu);
+ await testUtils.dom.click(list.$('.o_list_record_selector:first input'));
- testUtils.dom.click($actionMenu.find('button')); // open Action menu
- assert.strictEqual($actionMenu.find('.dropdown-item').length, 3,
- "there should be 3 actions");
- var $customAction = $actionMenu.find('.dropdown-item:last');
- assert.strictEqual($customAction.text().trim(), 'Action event',
- "the custom action should have 'Action event' as name");
+ await cpHelpers.toggleActionMenu(list);
+ assert.deepEqual(cpHelpers.getMenuItemTexts(list), ['Export', 'Delete', 'Action event']);
list.destroy();
});
- QUnit.test('execute a sidebar actions with correct params', async function (assert) {
+ QUnit.test('execute ActionMenus actions with correct params', async function (assert) {
assert.expect(12);
const list = await createView({
@@ -4285,39 +4284,40 @@ QUnit.module('Views', {
return this._super(...arguments);
},
viewOptions: {
- hasSidebar: true,
+ hasActionMenus: true,
},
});
- let $actionMenu = list.$('.o_cp_sidebar .o_dropdown:contains(Action)');
- assert.isNotVisible($actionMenu);
+ assert.containsNone(list.el, 'div.o_control_panel .o_cp_action_menus');
+
assert.containsN(list, '.o_data_row', 4);
// select all records
await testUtils.dom.click(list.$('thead .o_list_record_selector input'));
assert.containsN(list, '.o_list_record_selector input:checked', 5);
- assert.isVisible($actionMenu);
+ assert.containsOnce(list.el, 'div.o_control_panel .o_cp_action_menus');
- await testUtils.dom.click($actionMenu.find('button')); // open Action menu
- await testUtils.dom.click($actionMenu.find('.dropdown-item:contains(Custom Action)'));
+ await cpHelpers.toggleActionMenu(list);
+ await cpHelpers.toggleMenuItem(list, "Custom Action");
// unselect first record (will unselect the thead checkbox as well)
await testUtils.dom.click(list.$('tbody .o_list_record_selector:first input'));
assert.containsN(list, '.o_list_record_selector input:checked', 3);
- await testUtils.dom.click($actionMenu.find('button')); // open Action menu
- await testUtils.dom.click($actionMenu.find('.dropdown-item:contains(Custom Action)'));
+ await cpHelpers.toggleActionMenu(list);
+ await cpHelpers.toggleMenuItem(list, "Custom Action");
// add a domain and select first two records
await list.reload({ domain: [['bar', '=', true]] });
assert.containsN(list, '.o_data_row', 3);
assert.containsNone(list, '.o_list_record_selector input:checked');
- $actionMenu = list.$('.o_cp_sidebar .o_dropdown:contains(Action)');
+
await testUtils.dom.click(list.$('tbody .o_list_record_selector:nth(0) input'));
await testUtils.dom.click(list.$('tbody .o_list_record_selector:nth(1) input'));
assert.containsN(list, '.o_list_record_selector input:checked', 2);
- await testUtils.dom.click($actionMenu.find('button')); // open Action menu
- await testUtils.dom.click($actionMenu.find('.dropdown-item:contains(Custom Action)'));
+
+ await cpHelpers.toggleActionMenu(list);
+ await cpHelpers.toggleMenuItem(list, "Custom Action");
assert.verifySteps([
'{"action_id":44,"context":{"active_id":1,"active_ids":[1,2,3,4],"active_model":"foo","select_all":true,"active_domain":[]}}',
@@ -4374,13 +4374,13 @@ QUnit.module('Views', {
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
assert.strictEqual(document.activeElement, list.$('.o_data_row:first .o_data_cell:first input')[0]);
- // Press 'Tab' -> should go to next cell (still in first row)
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ // // Press 'Tab' -> should go to next cell (still in first row)
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row input[name="foo"]'), 'tab');
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
assert.strictEqual(document.activeElement, list.$('.o_data_row:first .o_data_cell:last input')[0]);
- // Press 'Tab' -> should go to next line (first cell)
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ // // Press 'Tab' -> should go to next line (first cell)
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row input[name="int_field"]'), 'tab');
assert.hasClass(list.$('.o_data_row:nth(1)'), 'o_selected_row');
assert.strictEqual(document.activeElement, list.$('.o_data_row:nth(1) .o_data_cell:first input')[0]);
@@ -4507,13 +4507,13 @@ QUnit.module('Views', {
// Press 'Tab' -> should go to next line
// add a value in the cell because the Tab on an empty first cell would activate the next widget in the view
await testUtils.fields.editInput(list.$('.o_selected_row input').eq(1), 11);
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row input[name="display_name"]'), 'tab');
assert.hasClass(list.$('.o_data_row:nth(3)'),'o_selected_row',
"fourth row should be in edition");
// Press 'Tab' -> should go back to first line as the create action isn't available
await testUtils.fields.editInput(list.$('.o_selected_row input').eq(1), 11);
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row input[name="display_name"]'), 'tab');
assert.hasClass(list.$('.o_data_row:first'),'o_selected_row',
"first row should be in edition");
@@ -6080,7 +6080,7 @@ QUnit.module('Views', {
"the second row should be selected");
// Keyboard navigation only interracts with selected elements
- await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input.o_field_widget'), 'enter');
+ await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input.o_field_widget[name="int_field"]'), 'enter');
assert.hasClass(list.$('.o_data_row:eq(3)'), 'o_selected_row',
"the fourth row should be selected");
@@ -6493,7 +6493,7 @@ QUnit.module('Views', {
});
QUnit.test('use the limit attribute in arch', async function (assert) {
- assert.expect(3);
+ assert.expect(4);
var list = await createView({
View: ListView,
@@ -6507,8 +6507,9 @@ QUnit.module('Views', {
},
});
- assert.strictEqual(list.pager.$el.text().trim(), '1-2 / 4',
- "pager should be correct");
+
+ assert.strictEqual(cpHelpers.getPagerValue(list), '1-2');
+ assert.strictEqual(cpHelpers.getPagerSize(list), '4');
assert.containsN(list, '.o_data_row', 2,
'should display 2 data rows');
@@ -6641,7 +6642,7 @@ QUnit.module('Views', {
return this._super.apply(this, arguments);
},
viewOptions: {
- hasSidebar: true,
+ hasActionMenus: true,
},
});
core.bus.on('clear_cache', list, assert.step.bind(assert, 'clear_cache'));
@@ -6658,8 +6659,8 @@ QUnit.module('Views', {
// delete a record
await testUtils.dom.click(list.$('.o_data_row:first .o_list_record_selector input'));
- await testUtils.dom.click(list.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(list.sidebar.$('a:contains(Delete)'));
+ await cpHelpers.toggleActionMenu(list);
+ await cpHelpers.toggleMenuItem(list, "Delete");
await testUtils.dom.click($('.modal-footer .btn-primary'));
assert.verifySteps([
@@ -6696,23 +6697,21 @@ QUnit.module('Views', {
},
});
+
// switch pages (should ask to scroll)
- await testUtils.dom.click(list.pager.$('.o_pager_next'));
- await testUtils.dom.click(list.pager.$('.o_pager_previous'));
+ await cpHelpers.pagerNext(list);
+ await cpHelpers.pagerPrevious(list);
assert.verifySteps(['scroll', 'scroll'],
"should ask to scroll when switching pages");
// change the limit (should not ask to scroll)
- await testUtils.dom.click(list.pager.$('.o_pager_value'));
- await testUtils.fields.editAndTrigger(list.pager.$('.o_pager_value input'),
- '1-2', ['blur']);
- assert.strictEqual(list.pager.$('.o_pager_value').text(), '1-2',
- "should have changed the limit");
-
+ await cpHelpers.setPagerValue(list, '1-2');
+ await testUtils.nextTick();
+ assert.strictEqual(cpHelpers.getPagerValue(list), '1-2');
assert.verifySteps([], "should not ask to scroll when changing the limit");
// switch pages again (should still ask to scroll)
- await testUtils.dom.click(list.pager.$('.o_pager_next'));
+ await cpHelpers.pagerNext(list);
assert.verifySteps(['scroll'], "this is still working after a limit change");
@@ -6895,9 +6894,9 @@ QUnit.module('Views', {
assert.containsN(list, '.o_group_header', 3); // page 1
assert.containsNone(list, '.o_data_row');
- assert.containsOnce(list, '.o_pager_counter'); // has a pager
+ assert.containsOnce(list, '.o_pager'); // has a pager
- await testUtils.dom.click(list.$('.o_pager_next')); // switch to page 2
+ await cpHelpers.pagerNext(list); // switch to page 2
assert.containsN(list, '.o_group_header', 1); // page 2
assert.containsNone(list, '.o_data_row');
@@ -6986,9 +6985,9 @@ QUnit.module('Views', {
assert.containsN(list, '.o_group_header', 10); // page 1
assert.containsN(list, '.o_data_row', 11); // one group contains two records
- assert.containsOnce(list, '.o_pager_counter'); // has a pager
+ assert.containsOnce(list, '.o_pager'); // has a pager
- await testUtils.dom.click(list.$('.o_pager_next')); // switch to page 2
+ await cpHelpers.pagerNext(list); // switch to page 2
assert.containsN(list, '.o_group_header', 7); // page 2
assert.containsN(list, '.o_data_row', 7);
@@ -7044,8 +7043,8 @@ QUnit.module('Views', {
assert.containsN(actionManager, '.o_group_header', 1); // page 2
// toggle a filter -> there should be only one group left (on page 1)
- await testUtils.dom.click(actionManager.$('.o_control_panel .o_search_options .o_filters_menu_button'));
- await testUtils.dom.click(actionManager.$('.o_control_panel .o_search_options .o_filters_menu .o_menu_item:first'));
+ await cpHelpers.toggleFilterMenu(actionManager);
+ await cpHelpers.toggleMenuItem(actionManager, 0);
assert.strictEqual(actionManager.$('.o_pager_counter').text().trim(), '1-1 / 1');
assert.containsN(actionManager, '.o_group_header', 1); // page 1
@@ -7314,19 +7313,19 @@ QUnit.module('Views', {
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
// Press 'Tab' -> should go to next line (still in first group)
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.hasClass(list.$('.o_data_row:nth(1)'), 'o_selected_row');
// Press 'Tab' -> should go to next line (still in first group)
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.hasClass(list.$('.o_data_row:nth(2)'), 'o_selected_row');
// Press 'Tab' -> should go to first line of next group
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.hasClass(list.$('.o_data_row:nth(3)'), 'o_selected_row');
// Press 'Tab' -> should go back to first line of first group
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
list.destroy();
@@ -7354,19 +7353,19 @@ QUnit.module('Views', {
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
// Press 'Tab' -> should go to next line (still in first group)
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.hasClass(list.$('.o_data_row:nth(1)'), 'o_selected_row');
// Press 'Tab' -> should go to next line (still in first group)
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.hasClass(list.$('.o_data_row:nth(2)'), 'o_selected_row');
// Press 'Tab' -> should go to first line of next group
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.hasClass(list.$('.o_data_row:nth(3)'), 'o_selected_row');
// Press 'Tab' -> should go back to first line of first group
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
list.destroy();
@@ -7394,19 +7393,19 @@ QUnit.module('Views', {
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
// Press 'Tab' -> should go to next line (still in first group)
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.hasClass(list.$('.o_data_row:nth(1)'), 'o_selected_row');
// Press 'Tab' -> should go to next line (still in first group)
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.hasClass(list.$('.o_data_row:nth(2)'), 'o_selected_row');
// Press 'Tab' -> should go to first line of next group
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.hasClass(list.$('.o_data_row:nth(3)'), 'o_selected_row');
// Press 'Tab' -> should go back to first line of first group
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.hasClass(list.$('.o_data_row:first'), 'o_selected_row');
list.destroy();
@@ -7550,20 +7549,20 @@ QUnit.module('Views', {
await testUtils.fields.editInput(list.$('.o_selected_row input[name="foo"]'), 'new value');
// Press 'Tab' -> should create a new record as we edited the previous one
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.containsN(list, '.o_data_row', 5);
assert.hasClass(list.$('.o_data_row:nth(3)'), 'o_selected_row');
// fill foo field for the new record and press 'tab' -> should create another record
await testUtils.fields.editInput(list.$('.o_selected_row input[name="foo"]'), 'new record');
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.containsN(list, '.o_data_row', 6);
assert.hasClass(list.$('.o_data_row:nth(4)'), 'o_selected_row');
// leave this new row empty and press tab -> should discard the new record and move to the
// next group
- await testUtils.fields.triggerKeydown(list.$('.o_selected_row input'), 'tab');
+ await testUtils.fields.triggerKeydown(list.$('.o_selected_row .o_input'), 'tab');
assert.containsN(list, '.o_data_row', 5);
assert.hasClass(list.$('.o_data_row:nth(4)'), 'o_selected_row');
@@ -7637,13 +7636,13 @@ QUnit.module('Views', {
assert.hasClass(list.$('tr.o_data_row:eq(1)'), 'o_selected_row');
// press enter in input should move to next record
- await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
+ await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row .o_input'), 'enter');
assert.hasClass(list.$('tr.o_data_row:eq(2)'), 'o_selected_row');
assert.doesNotHaveClass(list.$('tr.o_data_row:eq(1)'), 'o_selected_row');
// press enter on last row should create a new record
- await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
+ await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row .o_input'), 'enter');
assert.containsN(list, 'tr.o_data_row', 5);
assert.hasClass(list.$('tr.o_data_row:eq(3)'), 'o_selected_row');
@@ -7680,13 +7679,13 @@ QUnit.module('Views', {
assert.hasClass(list.$('tr.o_data_row:eq(1)'), 'o_selected_row');
// press enter in input should move to next record
- await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
+ await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row .o_input'), 'enter');
assert.hasClass(list.$('tr.o_data_row:eq(2)'), 'o_selected_row');
assert.doesNotHaveClass(list.$('tr.o_data_row:eq(1)'), 'o_selected_row');
// press enter on last row should move to first record of next group
- await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
+ await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row .o_input'), 'enter');
assert.hasClass(list.$('tr.o_data_row:eq(3)'), 'o_selected_row');
assert.doesNotHaveClass(list.$('tr.o_data_row:eq(2)'), 'o_selected_row');
@@ -7722,13 +7721,13 @@ QUnit.module('Views', {
assert.hasClass(list.$('tr.o_data_row:eq(1)'), 'o_selected_row');
// press enter in input should move to next record
- await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
+ await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row .o_input'), 'enter');
assert.hasClass(list.$('tr.o_data_row:eq(2)'), 'o_selected_row');
assert.doesNotHaveClass(list.$('tr.o_data_row:eq(1)'), 'o_selected_row');
// press enter on last row should move to first record of next group
- await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row input'), 'enter');
+ await testUtils.fields.triggerKeydown(list.$('tr.o_selected_row .o_input'), 'enter');
assert.hasClass(list.$('tr.o_data_row:eq(3)'), 'o_selected_row');
assert.doesNotHaveClass(list.$('tr.o_data_row:eq(2)'), 'o_selected_row');
diff --git a/addons/web/static/tests/views/pivot_tests.js b/addons/web/static/tests/views/pivot_tests.js
index 8ab46a0ca8d..0d17797ad74 100644
--- a/addons/web/static/tests/views/pivot_tests.js
+++ b/addons/web/static/tests/views/pivot_tests.js
@@ -3,11 +3,11 @@ odoo.define('web.pivot_tests', function (require) {
var core = require('web.core');
var PivotView = require('web.PivotView');
-var PivotRenderer = require('web.PivotRenderer');
var testUtils = require('web.test_utils');
var testUtilsDom = require('web.test_utils_dom');
var _t = core._t;
+const cpHelpers = testUtils.controlPanel;
var createActionManager = testUtils.createActionManager;
var createView = testUtils.createView;
var patchDate = testUtils.mock.patchDate;
@@ -388,10 +388,9 @@ QUnit.module('Views', {
var unpatchDate = patchDate(2016, 11, 20, 1, 0, 0);
var context = {
- timeRangeMenuData: {
- timeRange: ["&",["date",">=","2016-12-01"],["date","<","2017-01-01"]],
- timeRangeDescription: 'This Month',
- comparisonTimeRange: [],
+ time_ranges: {
+ field: 'date',
+ range: 'this_month'
}
};
var pivot = await createView({
@@ -411,7 +410,7 @@ QUnit.module('Views', {
viewOptions: {
context: context,
title: 'Partners',
- }
+ },
});
assert.hasClass(pivot.$('table'), 'o_enable_linking',
@@ -433,11 +432,10 @@ QUnit.module('Views', {
this.data.partner.records[3].date = '2016-11-03';
var context = {
- timeRangeMenuData: {
- timeRange: ["&",["date",">=","2016-12-01"],["date","<","2017-01-01"]],
- timeRangeDescription: 'This Month',
- comparisonTimeRange: ["&",["date",">=","2016-11-01"],["date","<","2017-12-01"]],
- comparisonTimeRangeDescription: 'Previous Period'
+ time_ranges: {
+ field: 'date',
+ range: 'this_month',
+ comparisonRange: 'previous_period',
}
};
@@ -470,7 +468,7 @@ QUnit.module('Views', {
viewOptions: {
context: context,
title: 'Partners',
- }
+ },
});
assert.hasClass(pivot.$('table'), 'o_enable_linking',
"root node should have classname 'o_enable_linking'");
@@ -1945,7 +1943,7 @@ QUnit.module('Views', {
});
QUnit.test('rendering of pivot view with comparison', async function (assert) {
- assert.expect(7);
+ assert.expect(8);
this.data.partner.records[0].date = '2016-12-15';
this.data.partner.records[1].date = '2016-12-17';
@@ -1966,31 +1964,40 @@ QUnit.module('Views', {
viewOptions: {
additionalMeasures: ['product_id'],
},
- intercepts: {
- create_filter: function (ev) {
- var data = ev.data;
- assert.deepEqual(data.filter.context.timeRangeMenuData, {
- timeRange: ["&", ["date", ">=", "2016-12-01"], ["date", "<", "2017-01-01"]],
- timeRangeDescription: 'This Month',
- comparisonTimeRange: ["&", ["date", ">=", "2016-11-01"], ["date", "<", "2016-12-01"]],
- comparisonTimeRangeDescription: 'Previous Period',
- });
+ mockRPC: function () {
+ return this._super.apply(this, arguments);
+ },
+ env: {
+ dataManager: {
+ create_filter: async function (filter) {
+ assert.deepEqual(filter.context, {
+ pivot_measures: ['__count'],
+ pivot_column_groupby: [],
+ pivot_row_groupby: ['product_id'],
+ group_by: [],
+ time_ranges: {
+ field: 'date',
+ range: 'this_month',
+ comparisonRange: 'previous_period',
+ }
+ })
+ }
}
},
});
+
// with no data
- await testUtils.dom.click(pivot.$('.o_time_range_menu_button'));
- await testUtils.dom.click(pivot.$('.o_time_range_menu .o_comparison_checkbox'));
- pivot.$('.o_time_range_selector').val('today');
- await testUtils.dom.click(pivot.$('.o_time_range_menu .o_apply_range'));
+ await cpHelpers.toggleTimeRangeMenu(pivot);
+ await cpHelpers.toggleTimeRangeMenuBox(pivot);
+ await cpHelpers.selectRange(pivot, 'today');
+ await cpHelpers.applyTimeRange(pivot);
assert.strictEqual(pivot.$('.o_pivot p.o_view_nocontent_empty_folder').length, 1);
// with data, no row groupby
- await testUtils.dom.click(pivot.$('.o_time_range_menu_button'));
- pivot.$('.o_time_range_selector').val('this_month');
- await testUtils.dom.click(pivot.$('.o_time_range_menu .o_apply_range'));
+ await cpHelpers.selectRange(pivot, 'this_month');
+ await cpHelpers.applyTimeRange(pivot);
assert.containsN(pivot, '.o_pivot thead tr:last th', 9,
"last header row should contains 9 cells (3*[This month, Previous Period, Variation]");
var values = [
@@ -2035,11 +2042,10 @@ QUnit.module('Views', {
];
assert.strictEqual(getCurrentValues(pivot), values.join());
- pivot.$('.o_search_options button:contains("Favorites")').click();
- var $favorites = pivot.$('.dropdown-menu.o_favorites_menu');
- $favorites.find('a.o_save_search').click();
- $favorites.find('.o_input').val('Fav').trigger('input');
- $favorites.find('button').click();
+ await cpHelpers.toggleFavoriteMenu(pivot);
+ await cpHelpers.toggleSaveFavorite(pivot);
+ await cpHelpers.editFavoriteName(pivot, 'Fav');
+ await cpHelpers.saveFavorite(pivot);
unpatchDate();
pivot.destroy();
@@ -2093,14 +2099,15 @@ QUnit.module('Views', {
},
});
+
// open time range menu
- await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu_button'));
+ await cpHelpers.toggleTimeRangeMenu(pivot);
// select 'Today' as range
- pivot.$('.o_control_panel .o_time_range_selector').val('today');
+ await cpHelpers.selectRange(pivot, 'today');
// check checkbox 'Compare To'
- await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu .o_comparison_checkbox'));
+ await cpHelpers.toggleTimeRangeMenuBox(pivot);
// Click on 'Apply' button
- await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu .o_apply_range'));
+ await cpHelpers.applyTimeRange(pivot);
// the time range menu configuration is by now: Date, Today, checkbox checked, Previous Period
// With the data above, the time ranges contain no record.
@@ -2109,13 +2116,11 @@ QUnit.module('Views', {
// are deactivated (exception: the 'Measures' button).
assert.ok(pivot.$('.o_control_panel button.o_pivot_download').prop('disabled'));
- // open time range menu
- await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu_button'));
// select 'This Month' as date range
- pivot.$('.o_control_panel .o_time_range_selector').val('this_month');
+ await cpHelpers.selectRange(pivot, 'this_month');
// Click on 'Apply' button
- await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu .o_apply_range'));
+ await cpHelpers.applyTimeRange(pivot);
// the time range menu configuration is by now: Date, This Month, checkbox checked, Previous Period
// With the data above, the time ranges contain some records.
// export data. Should execute 'get_file'
@@ -2177,11 +2182,12 @@ QUnit.module('Views', {
mockMock = true;
+
// activate 'This Month' and 'Previous Period' in time range menu
- await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu_button'));
- pivot.$('.o_control_panel .o_time_range_selector').val('this_month');
- await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu .o_comparison_checkbox'));
- await testUtils.dom.click(pivot.$('.o_control_panel .o_time_range_menu .o_apply_range'));
+ await cpHelpers.toggleTimeRangeMenu(pivot);
+ await cpHelpers.selectRange(pivot, 'this_month');
+ await cpHelpers.toggleTimeRangeMenuBox(pivot);
+ await cpHelpers.applyTimeRange(pivot);
var values = [
"4", "0", "100%",
@@ -2219,16 +2225,12 @@ QUnit.module('Views', {
},
});
+
// enable comparison mode
- var $cp = pivot.$('.o_control_panel');
- // open time range menu
- await testUtils.dom.click($cp.find('.o_time_range_menu_button'));
- // select 'This month' as range
- await testUtils.fields.editInput($cp.find('.o_time_range_selector'), 'this_month');
- // check checkbox 'Compare To'
- await testUtils.dom.click($cp.find('.o_time_range_menu .o_comparison_checkbox'));
- // click on 'Apply' button
- await testUtils.dom.click($cp.find('.o_time_range_menu .o_apply_range'));
+ await cpHelpers.toggleTimeRangeMenu(pivot);
+ await cpHelpers.selectRange(pivot, 'this_month');
+ await cpHelpers.toggleTimeRangeMenuBox(pivot);
+ await cpHelpers.applyTimeRange(pivot);
// initial sanity check
var values = [
@@ -2303,6 +2305,7 @@ QUnit.module('Views', {
assert.expect(16);
// create an action manager to test the interactions with the search view
var readGroupCount = 0;
+
var actionManager = await createActionManager({
data: this.data,
archs: {
@@ -2322,9 +2325,9 @@ QUnit.module('Views', {
mockRPC: function (route, args) {
if (args.method === 'read_group') {
assert.step('read_group');
- var domain = args.kwargs.domain;
+ const domain = args.kwargs.domain;
if ([0,1].indexOf(readGroupCount) !== -1) {
- assert.deepEqual(domain, [], 'initial domain empty');
+ assert.deepEqual(domain, [], 'domain empty');
} else if ([2,3,4,5].indexOf(readGroupCount) !== -1) {
assert.deepEqual(domain, [['foo', '=', 12]],
'domain conserved when back with breadcrumbs');
@@ -2333,12 +2336,12 @@ QUnit.module('Views', {
}
if (route === '/web/dataset/search_read') {
assert.step('search_read');
- var domain = args.domain;
+ const domain = args.domain;
assert.deepEqual(domain, [['customer', '=', 1], ['foo', '=', 12]],
'list domain is correct');
}
return this._super.apply(this, arguments);
- }
+ },
});
await actionManager.doAction({
@@ -2347,20 +2350,23 @@ QUnit.module('Views', {
views: [[false, 'pivot']],
});
- await testUtilsDom.click(actionManager.$('.o_filters_menu_button'));
- await testUtilsDom.click(actionManager.$('.o_menu_item:contains("Bayou")'));
- await testUtilsDom.click(actionManager.$('.o_pivot_cell_value:nth(1)'))
+ await cpHelpers.toggleFilterMenu(actionManager);
+ await cpHelpers.toggleMenuItem(actionManager, 0);
+ await testUtils.nextTick();
+
+ await testUtilsDom.click(actionManager.$('.o_pivot_cell_value:nth(1)'));
+ await testUtils.nextTick();
assert.containsOnce(actionManager, '.o_list_view');
- await testUtilsDom.click(actionManager.$('.o_control_panel .breadcrumb-item:first() a'));
+ await testUtilsDom.click(actionManager.$('.o_control_panel ol.breadcrumb li.breadcrumb-item').eq(0));
assert.verifySteps([
'read_group', 'read_group',
'read_group', 'read_group',
'search_read',
- 'read_group', 'read_group'])
+ 'read_group', 'read_group']);
actionManager.destroy();
});
@@ -2387,16 +2393,12 @@ QUnit.module('Views', {
},
});
+
// enable comparison mode
- var $cp = pivot.$('.o_control_panel');
- // open time range menu
- await testUtils.dom.click($cp.find('.o_time_range_menu_button'));
- // select 'This month' as range
- await testUtils.fields.editInput($cp.find('.o_time_range_selector'), 'this_month');
- // check checkbox 'Compare To'
- await testUtils.dom.click($cp.find('.o_time_range_menu .o_comparison_checkbox'));
- // click on 'Apply' button
- await testUtils.dom.click($cp.find('.o_time_range_menu .o_apply_range'));
+ await cpHelpers.toggleTimeRangeMenu(pivot);
+ await cpHelpers.selectRange(pivot, 'this_month');
+ await cpHelpers.toggleTimeRangeMenuBox(pivot);
+ await cpHelpers.applyTimeRange(pivot);
// initial sanity check
var values = [
@@ -2474,8 +2476,7 @@ QUnit.module('Views', {
[
'', 'Total', '',
'2016-12-15', '2016-12-17', '2016-11-22', '2016-11-03',
- ].join('')
- ,
+ ].join(''),
"The col headers should be as expected"
);
assert.strictEqual(
@@ -2489,24 +2490,19 @@ QUnit.module('Views', {
"The row headers should be as expected"
);
+
// enable comparison mode
- var $cp = pivot.$('.o_control_panel');
- // open time range menu
- await testUtils.dom.click($cp.find('.o_time_range_menu_button'));
- // select 'This month' as range
- await testUtils.fields.editInput($cp.find('.o_time_range_selector'), 'this_month');
- // check checkbox 'Compare To'
- await testUtils.dom.click($cp.find('.o_time_range_menu .o_comparison_checkbox'));
- // click on 'Apply' button
- await testUtils.dom.click($cp.find('.o_time_range_menu .o_apply_range'));
+ await cpHelpers.toggleTimeRangeMenu(pivot);
+ await cpHelpers.selectRange(pivot, 'this_month');
+ await cpHelpers.toggleTimeRangeMenuBox(pivot);
+ await cpHelpers.applyTimeRange(pivot);
assert.strictEqual(
pivot.$('th').slice(0, 7).text(),
[
'', 'Total', '',
'2016-12-15', '2016-12-17', '2016-11-22', '2016-11-03',
- ].join('')
- ,
+ ].join(''),
"The col headers should be as expected"
);
assert.strictEqual(
@@ -2551,10 +2547,10 @@ QUnit.module('Views', {
QUnit.test('Does not identify "false" with false as keys when creating group trees', async function (assert) {
assert.expect(2);
- this.data.partner.fields['favorite_animal'] = {string: "Favorite animal", type: "char", store: true}
- this.data.partner.records[0]['favorite_animal'] = 'Dog'
- this.data.partner.records[1]['favorite_animal'] = 'false'
- this.data.partner.records[2]['favorite_animal'] = 'Undefined'
+ this.data.partner.fields.favorite_animal = {string: "Favorite animal", type: "char", store: true};
+ this.data.partner.records[0].favorite_animal = 'Dog';
+ this.data.partner.records[1].favorite_animal = 'false';
+ this.data.partner.records[2].favorite_animal = 'Undefined';
var unpatchDate = patchDate(2016, 11, 20, 1, 0, 0);
var pivot = await createView({
@@ -2571,8 +2567,7 @@ QUnit.module('Views', {
pivot.$('th').slice(0, 2).text(),
[
'', 'Total', '',
- ].join('')
- ,
+ ].join(''),
"The col headers should be as expected"
);
assert.strictEqual(
@@ -2595,7 +2590,7 @@ QUnit.module('Views', {
QUnit.test('group bys added via control panel and expand Header do not stack', async function (assert) {
assert.expect(8);
- delete this.data.partner.fields['date'];
+ delete this.data.partner.fields.date;
var pivot = await createView({
View: PivotView,
@@ -2624,11 +2619,11 @@ QUnit.module('Views', {
"The row headers should be as expected"
);
- var $cp = pivot.$('.o_control_panel');
+
// open group by menu and add new groupby
- await testUtils.dom.click($cp.find('button span.fa-bars'));
- await testUtils.dom.click($cp.find('button.o_add_custom_group'));
- await testUtils.dom.click($cp.find('button.o_apply_group'));
+ await cpHelpers.toggleGroupByMenu(pivot);
+ await cpHelpers.toggleAddCustomGroup(pivot);
+ await cpHelpers.applyGroup(pivot);
assert.strictEqual(
pivot.$('th').slice(0, 2).text(),
@@ -2670,10 +2665,11 @@ QUnit.module('Views', {
"The row headers should be as expected"
);
- // open group by menu and add new groupby
- await testUtils.dom.click($cp.find('button span.fa-bars'));
- await testUtils.dom.click($cp.find('button.o_add_custom_group'));
- await testUtils.dom.click($cp.find('button.o_apply_group'));
+ // open groupby menu generator and add a new groupby
+ await cpHelpers.toggleGroupByMenu(pivot);
+ await cpHelpers.toggleAddCustomGroup(pivot);
+ await cpHelpers.selectGroup(pivot, 'bar');
+ await cpHelpers.applyGroup(pivot);
assert.strictEqual(
pivot.$('th').slice(0, 2).text(),
diff --git a/addons/web/static/tests/views/qweb_tests.js b/addons/web/static/tests/views/qweb_tests.js
index c7872690e49..19acf9b06c3 100644
--- a/addons/web/static/tests/views/qweb_tests.js
+++ b/addons/web/static/tests/views/qweb_tests.js
@@ -1,7 +1,6 @@
odoo.define('web.qweb_view_tests', function (require) {
"use strict";
-var qweb = require('web.qweb');
var utils = require('web.test_utils');
QUnit.module("Views", {
diff --git a/addons/web/static/tests/views/search_filter_menu_tests.js b/addons/web/static/tests/views/search_filter_menu_tests.js
deleted file mode 100644
index 62cfaccdc93..00000000000
--- a/addons/web/static/tests/views/search_filter_menu_tests.js
+++ /dev/null
@@ -1,206 +0,0 @@
-odoo.define('web.search_filters_menu_tests', function (require) {
-"use strict";
-
-var Domain = require('web.Domain');
-var FilterMenu = require('web.FilterMenu');
-var pyUtils = require('web.py_utils');
-var testUtils = require('web.test_utils');
-
-function createFilterMenu(filters, fields, params) {
- params = params || {};
- var target = params.debug ? document.body : $('#qunit-fixture');
- var menu = new FilterMenu(null, filters, fields);
- testUtils.mock.addMockEnvironment(menu, params);
- return menu.appendTo(target).then(function() {
- return menu;
- });
-}
-
-QUnit.module('FilterMenu', {
- beforeEach: function () {
- this.filters = [
- {
- isActive: false,
- description: 'some filter',
- domain: '',
- groupNumber: 1,
- },
- ];
- this.fields = {
- boolean_field: {string: "Boolean Field", type: "boolean", default: true, searchable: true},
- date_field: {string: "A date", type: "date", searchable: true},
- char_field: {string: "Char Field", type: "char", default: "foo", searchable: true, trim: true},
- };
- },
-}, function () {
-
- QUnit.test('simple rendering with no filter', async function (assert) {
- assert.expect(3);
-
- var filterMenu = await createFilterMenu([], this.fields);
- await testUtils.dom.click(filterMenu.$('span.fa-filter'));
- assert.containsNone(filterMenu, '.dropdown-divider');
- assert.containsNone(filterMenu, '.o_add_filter_menu');
- assert.containsOnce(filterMenu, '.o_add_custom_filter',
- 'should have one element: a add custom filter item');
- filterMenu.destroy();
- });
-
- QUnit.test('simple rendering with a filter', async function (assert) {
- assert.expect(2);
-
- var filterMenu = await createFilterMenu(this.filters, this.fields);
- assert.containsN(filterMenu, '.dropdown-divider, .dropdown-item, .o_add_custom_filter', 4,
- 'should have 4 elements: a hidden separator, a filter, a separator, a add custom filter item');
- assert.containsOnce(filterMenu, '.o_add_custom_filter');
- filterMenu.destroy();
- });
-
- QUnit.test('click on add custom filter opens the submenu', async function (assert) {
- assert.expect(3);
-
- var filterMenu = await createFilterMenu([], this.fields);
- // open menu dropdown
- await testUtils.dom.click(filterMenu.$('span.fa-filter'));
- // open add custom filter submenu
- await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
- assert.containsNone(filterMenu, '.dropdown-divider');
- assert.isVisible(filterMenu.$('.o_add_filter_menu'));
- assert.containsN(filterMenu, '.dropdown-item, .dropdown-item-text', 3,
- 'should have 3 elements: a add custom filter item, a proposition, a apply button + add condition button');
-
- filterMenu.destroy();
- });
-
- QUnit.test('removing last prop disable the apply button', async function (assert) {
- assert.expect(2);
-
- var filterMenu = await createFilterMenu([], this.fields);
- // open menu dropdown and custom filter submenu
- await testUtils.dom.click(filterMenu.$('span.fa-filter'));
- await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
-
- // remove the current unique proposition
- await testUtils.dom.click(filterMenu.$('.o_searchview_extended_delete_prop'));
-
- assert.containsNone(filterMenu, '.dropdown-divider');
- assert.containsN(filterMenu, '.dropdown-item, .dropdown-item-text', 2,
- 'should have 2 elements: a add custom filter item, a apply button + add condition button');
-
- filterMenu.destroy();
- });
-
- QUnit.test('readding a proposition reenable apply button', async function (assert) {
- assert.expect(1);
-
- var filterMenu = await createFilterMenu([], this.fields);
- // open menu dropdown and custom filter submenu, remove existing prop
- await testUtils.dom.click(filterMenu.$('span.fa-filter'));
- await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
- await testUtils.dom.click(filterMenu.$('.o_searchview_extended_delete_prop'));
- // read a proposition
- await testUtils.dom.click(filterMenu.$('.o_add_condition'));
- assert.ok(!filterMenu.$('.o_apply_filter').attr('disabled'));
-
- filterMenu.destroy();
- });
-
- QUnit.test('adding a simple filter works', async function (assert) {
- assert.expect(6);
-
- delete this.fields.date_field;
- var filterMenu = await createFilterMenu([], this.fields, {
- intercepts: {
- new_filters: function (ev) {
- var filter = ev.data.filters[0];
- assert.strictEqual(filter.type, 'filter');
- assert.strictEqual(filter.description, 'Boolean Field is true');
- assert.strictEqual(filter.domain, '[[\"boolean_field\",\"=\",True]]');
- filterMenu.update([{
- isActive: true,
- description: '?',
- domain: '?',
- groupNumber: 1,
- }]);
- },
- },
- });
- // open menu dropdown and custom filter submenu, remove existing prop
- await testUtils.dom.click(filterMenu.$('span.fa-filter'));
- await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
- // click on apply to activate filter
- await testUtils.dom.click(filterMenu.$('.o_apply_filter'));
- assert.containsNone(filterMenu, '.o_filter_condition');
- assert.containsN(filterMenu, '.dropdown-divider', 2);
- assert.isNotVisible(filterMenu.$('.dropdown-divider').eq(0));
- filterMenu.destroy();
- });
-
- QUnit.test('commit search with an extended proposition with field char does not cause a crash', async function (assert) {
- assert.expect(6);
-
- this.fields = {many2one_field: {string: "Trululu", type: "many2one", relation: 'partner', selectable: true, searchable: true}};
-
- var expectedDomains = [
- [['many2one_field','ilike', `a`]],
- [['many2one_field','ilike', `"a"`]],
- [['many2one_field','ilike', `'a'`]],
- [['many2one_field','ilike', `'`]],
- [['many2one_field','ilike', `"`]],
- [['many2one_field','ilike', `\\`]],
- ];
-
- var filterMenu = await createFilterMenu([], this.fields, {
- intercepts: {
- new_filters: function (ev) {
- var filter = ev.data.filters[0];
- // this step combine a tokenization/parsing followed by a string formatting
- var domain = pyUtils.assembleDomains([filter.domain]);
- domain = Domain.prototype.stringToArray(domain);
- assert.deepEqual(domain, expectedDomains.shift());
- },
- }
- });
-
- // open menu dropdown and custom filter submenu, select trululu field and enter string `a`, then click apply
- await testUtils.dom.click(filterMenu.$('span.fa-filter'));
- await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
- await testUtils.fields.editSelect(filterMenu.$('.o_filter_condition select.o_input.o_searchview_extended_prop_field'), 'many2one_field');
- await testUtils.fields.editInput(filterMenu.$('.o_filter_condition .o_searchview_extended_prop_value input'), `a`);
- await testUtils.dom.click(filterMenu.$('.o_apply_filter'));
-
-
- // open custom filter submenu, select trululu field and enter string `"a"`, then click apply
- await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
- await testUtils.fields.editSelect(filterMenu.$('.o_filter_condition select.o_input.o_searchview_extended_prop_field'), 'many2one_field');
- await testUtils.fields.editInput(filterMenu.$('.o_filter_condition .o_searchview_extended_prop_value input'), `"a"`);
- await testUtils.dom.click(filterMenu.$('.o_apply_filter'));
-
- // open custom filter submenu, select trululu field and enter string `'a'`, then click apply
- await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
- await testUtils.fields.editSelect(filterMenu.$('.o_filter_condition select.o_input.o_searchview_extended_prop_field'), 'many2one_field');
- await testUtils.fields.editInput(filterMenu.$('.o_filter_condition .o_searchview_extended_prop_value input'), `'a'`);
- await testUtils.dom.click(filterMenu.$('.o_apply_filter'));
-
- // open custom filter submenu, select trululu field and enter string `'`, then click apply
- await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
- await testUtils.fields.editSelect(filterMenu.$('.o_filter_condition select.o_input.o_searchview_extended_prop_field'), 'many2one_field');
- await testUtils.fields.editInput(filterMenu.$('.o_filter_condition .o_searchview_extended_prop_value input'), `'`);
- await testUtils.dom.click(filterMenu.$('.o_apply_filter'));
-
- // open custom filter submenu, select trululu field and enter string `"`, then click apply
- await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
- await testUtils.fields.editSelect(filterMenu.$('.o_filter_condition select.o_input.o_searchview_extended_prop_field'), 'many2one_field');
- await testUtils.fields.editInput(filterMenu.$('.o_filter_condition .o_searchview_extended_prop_value input'), `"`);
- await testUtils.dom.click(filterMenu.$('.o_apply_filter'));
-
- // open custom filter submenu, select trululu field and enter string `\`, then click apply
- await testUtils.dom.click(filterMenu.$('.o_add_custom_filter'));
- await testUtils.fields.editSelect(filterMenu.$('.o_filter_condition select.o_input.o_searchview_extended_prop_field'), 'many2one_field');
- await testUtils.fields.editInput(filterMenu.$('.o_filter_condition .o_searchview_extended_prop_value input'), `\\`);
- await testUtils.dom.click(filterMenu.$('.o_apply_filter'));
-
- filterMenu.destroy();
- });
-});
-});
diff --git a/addons/web/static/tests/views/search_groupby_menu_tests.js b/addons/web/static/tests/views/search_groupby_menu_tests.js
deleted file mode 100644
index 6ff0e7eaf13..00000000000
--- a/addons/web/static/tests/views/search_groupby_menu_tests.js
+++ /dev/null
@@ -1,200 +0,0 @@
-odoo.define('web.search_groupby_menu_tests', function (require) {
-"use strict";
-
-var GroupByMenu = require('web.GroupByMenu');
-var testUtils = require('web.test_utils');
-var controlPanelViewParameters = require('web.controlPanelViewParameters');
-var INTERVAL_OPTIONS = controlPanelViewParameters.INTERVAL_OPTIONS;
-
-function createGroupByMenu(groupBys, fields, params) {
- params = params || {};
- var target = params.debug ? document.body : $('#qunit-fixture');
- var menu = new GroupByMenu(null, groupBys, fields);
- testUtils.mock.addMockEnvironment(menu, params);
- return menu.appendTo(target).then(function() {
- return menu;
- });
-}
-
-QUnit.module('GroupByMenu', {
- beforeEach: function () {
- this.groupBys = [
- {
- description: 'some group by',
- groupNumber: 1,
- isActive: false,
- },
- ];
- this.fields = {
- fieldName: {sortable: true, string: 'Super Date', type: 'date'}
- };
- },
-}, function () {
-
- QUnit.test('simple rendering with no filter and no field', async function (assert) {
- assert.expect(1);
-
- var groupByMenu = await createGroupByMenu([], {});
- // open groupBy menu
- testUtils.dom.click(groupByMenu.$('button:first'));
- assert.containsNone(groupByMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text',
- 'should have 0 element');
-
- groupByMenu.destroy();
- });
-
- QUnit.test('simple rendering', async function (assert) {
- assert.expect(2);
-
- var groupByMenu = await createGroupByMenu(this.groupBys, this.fields);
- // open groupBy menu
- await testUtils.dom.click(groupByMenu.$('button:first'));
- assert.containsN(groupByMenu, '.dropdown-divider, .dropdown-item', 4);
- assert.strictEqual(groupByMenu.$('.o_menu_item').text().trim(), 'some group by',
- 'should have proper filter name');
-
- groupByMenu.destroy();
- });
-
- QUnit.test('simple rendering with no filter but fields', async function (assert) {
- assert.expect(1);
-
- var groupByMenu = await createGroupByMenu(
- [],
- {fieldName: {sortable: true, string: 'Super Date', type: 'date'}}
- );
- await testUtils.nextTick();
- await testUtils.dom.click(groupByMenu.$('button:first'));
- assert.containsOnce(groupByMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 'should have 1 element');
-
- groupByMenu.destroy();
- });
-
- QUnit.test('click on add custom group toggle group selector', async function (assert) {
- assert.expect(2);
-
- var groupByMenu = await createGroupByMenu([],
- {fieldName: {sortable: true, string: 'Super Date', type: 'date'}}
- );
- await testUtils.dom.click(groupByMenu.$('button:first'));
- var selector = groupByMenu.$('select.o_group_selector');
- assert.ok(!selector.is(":visible"), 'should be invisible');
- await testUtils.dom.click(groupByMenu.$('.o_add_custom_group'));
- selector = groupByMenu.$('select.o_group_selector');
- assert.ok(selector.is(":visible"), 'should be visible');
-
- groupByMenu.destroy();
- });
-
- QUnit.test('select a groupBy of no date type in Add Custom Group menu add properly that groupBy to menu', async function (assert) {
- assert.expect(6);
-
- var groupByMenu = await createGroupByMenu(
- [],
- {
- fieldName: {sortable: true, name: 'candlelight', string: 'Candlelight', type: 'boolean'},
- },
- {
- intercepts: {
- new_groupBy: function (ev) {
- assert.strictEqual(ev.data.description, 'Candlelight');
- assert.strictEqual(ev.data.fieldName, 'fieldName');
- assert.strictEqual(ev.data.fieldType, 'boolean');
- assert.strictEqual(ev.data.type, 'groupBy');
- groupByMenu.update([{
- description: 'Candlelight',
- groupNumber: 1,
- isActive: true,
- }]);
- },
- },
- }
- );
- await testUtils.nextTick();
- await testUtils.dom.click(groupByMenu.$('button:first'));
- await testUtils.dom.click(groupByMenu.$('.o_add_custom_group'));
- assert.strictEqual(groupByMenu.$('select').val(), 'fieldName',
- 'the select value should be "fieldName"');
- await testUtils.dom.click(groupByMenu.$('button.o_apply_group'));
- assert.containsOnce(groupByMenu, '.o_menu_item > .dropdown-item.selected', 'there should be a groupby selected');
- groupByMenu.destroy();
- });
-
- QUnit.test('select a groupBy of date type in Add Custom Group menu add properly that groupBy to menu', async function (assert) {
- assert.expect(13);
-
- INTERVAL_OPTIONS = INTERVAL_OPTIONS.map(function (option) {
- return _.extend(option, {description: option.description.toString()});
- });
-
- var groupByMenu = await createGroupByMenu(
- [],
- this.fields,
- {
- intercepts: {
- new_groupBy: function (ev) {
- assert.strictEqual(ev.data.description, 'Super Date');
- assert.strictEqual(ev.data.fieldName, 'fieldName');
- assert.strictEqual(ev.data.fieldType, 'date');
- assert.strictEqual(ev.data.type, 'groupBy');
- assert.strictEqual(ev.data.hasOptions, true);
- assert.deepEqual(ev.data.options, controlPanelViewParameters.INTERVAL_OPTIONS);
- assert.strictEqual(ev.data.defaultOptionId, controlPanelViewParameters.DEFAULT_INTERVAL);
- assert.strictEqual(ev.data.currentOptionIds.size, 0);
- groupByMenu.update([{
- description: 'Super Date',
- fieldName: 'fieldName',
- groupNumber: 1,
- isActive: true,
- hasOptions: true,
- options: controlPanelViewParameters.INTERVAL_OPTIONS,
- currentOptionIds: new Set([controlPanelViewParameters.DEFAULT_INTERVAL]),
- }]);
- },
- },
- }
- );
- // open groupBy menu
- await testUtils.dom.click(groupByMenu.$('button:first'));
- // open Add Custom Group submenu
- await testUtils.dom.click(groupByMenu.$('.o_add_custom_group'));
- // select fieldName
- assert.strictEqual(groupByMenu.$('select').val(), 'fieldName',
- 'the select value should be "fieldName"');
- // create new groupBy of type date
- await testUtils.dom.click(groupByMenu.$('button.o_apply_group'));
- assert.strictEqual(groupByMenu.$('.o_menu_item > .dropdown-item.selected').length, 1,
- 'there should be a groupby selected');
- assert.strictEqual(groupByMenu.$('.o_menu_item .o_submenu_switcher').length, 1,
- 'there should be options available');
- // open options submenu
- await testUtils.dom.click(groupByMenu.$('.o_menu_item .o_submenu_switcher'));
- assert.strictEqual(groupByMenu.$('.o_item_option').length, 5,
- 'there should be five options available');
- assert.strictEqual(groupByMenu.$('.o_add_custom_group').length, 0,
- 'there should be no more a Add Custome Group submenu');
-
- groupByMenu.destroy();
- });
-
- QUnit.test('custom group by dropdown should not have ID field', async function (assert) {
- assert.expect(2);
-
- this.fields.id = {sortable: true, string: 'ID', type: 'integer'};
-
- var groupByMenu = await createGroupByMenu([], this.fields);
- // open groupBy menu
- await testUtils.dom.click(groupByMenu.$('button:first'));
- // open Add Custom Group submenu
- await testUtils.dom.click(groupByMenu.$('.o_add_custom_group'))
-
- assert.containsOnce(groupByMenu, '.o_group_selector option',
- 'groupby menu should have only one option');
- // custom group by should not have 'ID' field
- assert.containsNone(groupByMenu, '.o_group_selector option[value="id"]',
- 'id field should not be in custom group by');
-
- groupByMenu.destroy();
- });
-});
-});
diff --git a/addons/web/static/tests/views/search_panel_tests.js b/addons/web/static/tests/views/search_panel_tests.js
index 632158d9b1e..11cf8b03513 100644
--- a/addons/web/static/tests/views/search_panel_tests.js
+++ b/addons/web/static/tests/views/search_panel_tests.js
@@ -7,6 +7,7 @@ var KanbanView = require('web.KanbanView');
var RamStorage = require('web.RamStorage');
var testUtils = require('web.test_utils');
+const cpHelpers = testUtils.controlPanel;
var createActionManager = testUtils.createActionManager;
var createView = testUtils.createView;
@@ -1396,7 +1397,7 @@ QUnit.module('Views', {
]);
// go to page 2 (the domain doesn't change, so the filters should not be reloaded)
- await testUtils.dom.click(kanban.$('.o_pager_next'));
+ await cpHelpers.pagerNext(kanban);
assert.verifySteps([
'/web/dataset/search_read',
@@ -1935,16 +1936,17 @@ QUnit.module('Views', {
archs: this.archs,
data: this.data,
});
-
await actionManager.doAction(1);
+
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_kanban_view');
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_search_panel');
- await testUtils.dom.click(actionManager.$('.o_cp_switch_pivot'));
+ await cpHelpers.switchView(actionManager, 'pivot');
+ await testUtils.nextTick();
assert.containsOnce(actionManager, '.o_content .o_pivot');
assert.containsNone(actionManager, '.o_content .o_search_panel');
- await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
+ await cpHelpers.switchView(actionManager, 'list');
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_list_view');
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_search_panel');
@@ -1972,16 +1974,16 @@ QUnit.module('Views', {
archs: this.archs,
data: this.data,
});
-
await actionManager.doAction(1);
+
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_kanban_view');
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_search_panel');
- await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
+ await cpHelpers.switchView(actionManager, 'list');
assert.containsOnce(actionManager, '.o_content .o_list_view');
assert.containsNone(actionManager, '.o_content .o_search_panel');
- await testUtils.dom.click(actionManager.$('.o_cp_switch_pivot'));
+ await cpHelpers.switchView(actionManager, 'pivot');
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_pivot');
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_search_panel');
@@ -2003,8 +2005,8 @@ QUnit.module('Views', {
return this._super.apply(this, arguments);
},
});
-
await actionManager.doAction(1);
+
assert.hasClass(actionManager.$('.o_search_panel_category_value:first header'), 'active');
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 4);
@@ -2013,7 +2015,7 @@ QUnit.module('Views', {
assert.hasClass(actionManager.$('.o_search_panel_category_value:nth(1) header'), 'active');
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 2);
- await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
+ await cpHelpers.switchView(actionManager, 'list');
assert.hasClass(actionManager.$('.o_search_panel_category_value:nth(1) header'), 'active');
assert.containsN(actionManager, '.o_data_row', 2);
@@ -2022,7 +2024,7 @@ QUnit.module('Views', {
assert.hasClass(actionManager.$('.o_search_panel_category_value:nth(2) header'), 'active');
assert.containsN(actionManager, '.o_data_row', 2);
- await testUtils.dom.click(actionManager.$('.o_cp_switch_kanban'));
+ await cpHelpers.switchView(actionManager, 'kanban');
assert.hasClass(actionManager.$('.o_search_panel_category_value:nth(2) header'), 'active');
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 2);
@@ -2052,8 +2054,8 @@ QUnit.module('Views', {
return this._super.apply(this, arguments);
},
});
-
await actionManager.doAction(1);
+
assert.containsNone(actionManager, '.o_search_panel_filter_value input:checked');
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 4);
@@ -2062,7 +2064,7 @@ QUnit.module('Views', {
assert.containsOnce(actionManager, '.o_search_panel_filter_value input:checked');
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 1);
- await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
+ await cpHelpers.switchView(actionManager, 'list');
assert.containsOnce(actionManager, '.o_search_panel_filter_value input:checked');
assert.containsN(actionManager, '.o_data_row', 1);
@@ -2071,7 +2073,7 @@ QUnit.module('Views', {
assert.containsN(actionManager, '.o_search_panel_filter_value input:checked', 2);
assert.containsN(actionManager, '.o_data_row', 4);
- await testUtils.dom.click(actionManager.$('.o_cp_switch_kanban'));
+ await cpHelpers.switchView(actionManager, 'kanban');
assert.containsN(actionManager, '.o_search_panel_filter_value input:checked', 2);
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 4);
@@ -2094,8 +2096,8 @@ QUnit.module('Views', {
archs: this.archs,
data: this.data,
});
-
await actionManager.doAction(1);
+
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_kanban_view');
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_search_panel');
assert.containsNone(actionManager, '.o_search_panel_filter_value input:checked');
@@ -2107,13 +2109,13 @@ QUnit.module('Views', {
assert.containsN(actionManager, '.o_kanban_record:not(.o_kanban_ghost)', 1);
// switch to pivot
- await testUtils.dom.click(actionManager.$('.o_cp_switch_pivot'));
+ await cpHelpers.switchView(actionManager, 'pivot');
assert.containsOnce(actionManager, '.o_content .o_pivot');
assert.containsNone(actionManager, '.o_content .o_search_panel');
assert.strictEqual(actionManager.$('.o_pivot_cell_value').text(), '15');
// switch to list
- await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
+ await cpHelpers.switchView(actionManager, 'list');
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_list_view');
assert.containsOnce(actionManager, '.o_content.o_controller_with_searchpanel .o_search_panel');
assert.containsOnce(actionManager, '.o_search_panel_filter_value input:checked');
@@ -2192,10 +2194,10 @@ QUnit.module('Views', {
return this._super.apply(this, arguments);
},
});
-
await actionManager.doAction(1);
- await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
- await testUtils.dom.click(actionManager.$('.o_cp_switch_kanban'));
+
+ await cpHelpers.switchView(actionManager, 'list');
+ await cpHelpers.switchView(actionManager, 'kanban');
assert.verifySteps([
'/web/action/load',
@@ -2226,18 +2228,19 @@ QUnit.module('Views', {
actionManager.$el.css('max-height', 300);
await actionManager.doAction(1);
+
assert.containsOnce(actionManager, '.o_content .o_kanban_view');
assert.strictEqual(actionManager.$('.o_search_panel').scrollTop(), 0);
// simulate a scroll in the search panel and switch into list
actionManager.$('.o_search_panel').scrollTop(50);
- await testUtils.dom.click(actionManager.$('.o_cp_switch_list'));
+ await cpHelpers.switchView(actionManager, 'list');
assert.containsOnce(actionManager, '.o_content .o_list_view');
assert.strictEqual(actionManager.$('.o_search_panel').scrollTop(), 50);
// simulate another scroll and switch back to kanban
actionManager.$('.o_search_panel').scrollTop(30);
- await testUtils.dom.click(actionManager.$('.o_cp_switch_kanban'));
+ await cpHelpers.switchView(actionManager, 'kanban');
assert.containsOnce(actionManager, '.o_content .o_kanban_view');
assert.strictEqual(actionManager.$('.o_search_panel').scrollTop(), 30);
diff --git a/addons/web/static/tests/views/search_view_tests.js b/addons/web/static/tests/views/search_view_tests.js
deleted file mode 100644
index 5dbf8361628..00000000000
--- a/addons/web/static/tests/views/search_view_tests.js
+++ /dev/null
@@ -1,1928 +0,0 @@
-odoo.define('web.search_view_tests', function (require) {
-"use strict";
-
-var FormView = require('web.FormView');
-var GraphView = require('web.GraphView');
-var testUtils = require('web.test_utils');
-
-var createActionManager = testUtils.createActionManager;
-var createControlPanel = testUtils.createControlPanel;
-var createView = testUtils.createView;
-var patchDate = testUtils.mock.patchDate;
-var session = require('web.session');
-
-var controlPanelViewParameters = require('web.controlPanelViewParameters');
-const PERIOD_OPTIONS_IDS = controlPanelViewParameters.PERIOD_OPTIONS.map(o => o.optionId);
-const OPTION_GENERATOR_IDS = controlPanelViewParameters.OPTION_GENERATORS.map(o => o.optionId);
-
-QUnit.module('Search View', {
- beforeEach: function () {
- this.data = {
- partner: {
- fields: {
- date_field: {string: "Date", type: "date", store: true, sortable: true},
- birthday: {string: "Birthday", type: "date", store: true, sortable: true},
- foo: {string: "Foo", type: "char", store: true, sortable: true},
- bar: {string: "Bar", type: "many2one", relation: 'partner'},
- float_field: {string: "Float", type: "float", group_operator: 'sum'},
- },
- records: [
- {id: 1, display_name: "First record", foo: "yop", bar: 2, date_field: "2017-01-25", birthday: "1983-07-15", float_field: 1},
- {id: 2, display_name: "Second record", foo: "blip", bar: 1, date_field: "2017-01-24", birthday: "1982-06-04",float_field: 2},
- {id: 3, display_name: "Third record", foo: "gnap", bar: 1, date_field: "2017-01-13", birthday: "1985-09-13",float_field: 1.618},
- {id: 4, display_name: "Fourth record", foo: "plop", bar: 2, date_field: "2017-02-25", birthday: "1983-05-05",float_field: -1},
- {id: 5, display_name: "Fifth record", foo: "zoup", bar: 2, date_field: "2016-01-25", birthday: "1800-01-01",float_field: 13},
- ],
- },
- pony: {
- fields: {
- name: {string: 'Name', type: 'char'},
- },
- records: [
- {id: 4, name: 'Twilight Sparkle'},
- {id: 6, name: 'Applejack'},
- {id: 9, name: 'Fluttershy'}
- ],
- },
- };
-
- this.actions = [{
- id: 1,
- name: 'Partners Action 1',
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[false, 'list']],
- }, {
- id: 2,
- name: 'Partners Action 2',
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[false, 'list']],
- search_view_id: [2, 'search'],
- }, {
- id: 3,
- name: 'Partners Action 3',
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[false, 'kanban']],
- search_view_id: [2, 'search'],
- }, {
- id: 4,
- name: 'Partners Action 4',
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[false, 'graph']],
- search_view_id: [3, 'search'],
- }, {
- id: 5,
- name: 'Partners Action 5',
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[2, 'list']],
- search_view_id: [4, 'search'],
- }, {
- id: 6,
- name: 'Partners Action 6',
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[2, 'list']],
- search_view_id: [5, 'search'],
- }, {
- id: 7,
- name: 'Partners Action 7',
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[2, 'list']],
- search_view_id: [6, 'search'],
- }, {
- id: 8,
- name: 'Partners Action 8',
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[2, 'list']],
- search_view_id: [7, 'search'],
- }, {
- id: 9,
- name: 'Partners Action 9',
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[false, 'pivot']],
- search_view_id: [5, 'search'],
- }, {
- id: 10,
- name: 'Partners Action 10',
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[false, 'pivot']],
- search_view_id: [8, 'search'],
- }, {
- id: 11,
- name: 'Partners Action 11',
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[2, 'list']],
- search_view_id: [8, 'search'],
- }, {
- id: 12,
- name: 'Partners Action 12',
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[2, 'list']],
- search_view_id: [9, 'search'],
- }
- ];
-
- this.archs = {
- // list views
- 'partner,false,list': '<tree><field name="foo"/></tree>',
- 'partner,2,list': '<tree><field name="foo"/></tree>',
-
- // kanban views
- 'partner,false,kanban': '<kanban><templates><t t-name="kanban-box">' +
- '<div class="oe_kanban_global_click"><field name="foo"/></div>' +
- '</t></templates></kanban>',
-
- // graph views
- 'partner,false,graph': '<graph>' +
- '<field name="date_field" type="row" interval="day"/>' +
- '<field name="float_field" type="measure"/>' +
- '</graph>',
-
- // pivot views
- 'partner,false,pivot': '<pivot>' +
- '<field name="date_field" type="row" interval="day"/>' +
- '<field name="float_field" type="measure"/>' +
- '</pivot>',
-
- // search views
- 'partner,false,search': '<search>'+
- '<filter string="candle" name="itsName" context="{\'group_by\': \'foo\'}"/>' +
- '</search>',
- 'partner,2,search': '<search>'+
- '<filter string="Date" name="coolName" context="{\'group_by\': \'date_field\'}"/>' +
- '</search>',
- 'partner,3,search': '<search>'+
- '<filter string="float" name="positive" domain="[(\'float_field\', \'>=\', 0)]"/>' +
- '</search>',
- 'partner,4,search': '<search>'+
- '<filter string="Date" name="coolName" context="{\'group_by\': \'date_field:day\'}"/>' +
- '</search>',
- 'partner,5,search': '<search>'+
- '<filter string="Date Field Filter" name="positive" date="date_field"/>' +
- '<filter string="Date Field Groupby" name="coolName" context="{\'group_by\': \'date_field:day\'}"/>' +
- '</search>',
- 'partner,6,search': '<search>'+
- '<filter string="Date" name="coolName" context="{\'group_by\': \'date_field:day\'}"/>' +
- '<separator/>' +
- '<filter string="Bar" name="superName" context="{\'group_by\': \'bar\'}"/>' +
- '</search>',
- 'partner,7,search': '<search>'+
- '<filter string="1" name="coolName1" date="date_field"/>' +
- '<separator/>' +
- '<filter string="2" name="coolName2" date="birthday"/>' +
- '<separator/>' +
- '<filter string="3" name="coolName3" domain="[]"/>' +
- '<separator/>' +
- '<filter string="4" name="coolName4" domain="[]"/>' +
- '<separator/>' +
- '<filter string="5" name="coolName5" domain="[]"/>' +
- '<separator/>' +
- '<filter string="6" name="coolName6" domain="[]"/>' +
- '<separator/>' +
- '<filter string="7" name="coolName7" domain="[]"/>' +
- '<separator/>' +
- '<filter string="8" name="coolName8" domain="[]"/>' +
- '<separator/>' +
- '<filter string="9" name="coolName9" domain="[]"/>' +
- '<separator/>' +
- '<filter string="10" name="coolName10" domain="[]"/>' +
- '<separator/>' +
- '<filter string="11" name="coolName11" domain="[]"/>' +
- '</search>',
- 'partner,8,search': '<search>'+
- '<field name="foo"/>' +
- '<field name="date_field"/>' +
- '<field name="birthday"/>' +
- '<field name="bar" context="{\'bar\': self}"/>' +
- '<field name="float_field"/>' +
- '<filter string="Date Field Filter" name="positive" date="date_field"/>' +
- '<filter string="Date Field Groupby" name="coolName" context="{\'group_by\': \'date_field:day\'}"/>' +
- '</search>',
- 'partner,9,search': '<search>'+
- '<filter string="float" name="positive" domain="[(\'date_field\', \'>=\', (context_today() + relativedelta()).strftime(\'%Y-%m-%d\'))]"/>' +
- '</search>',
- 'partner,10,search': '<search>'+
- '<field string="Foo" name="foo"/>' +
- '<filter string="Date Field Filter" name="positive" date="date_field"/>' +
- '<filter string="Date Field Groupby" name="coolName" context="{\'group_by\': \'date_field:day\'}"/>' +
- '</search>',
- };
-
-
- // assuming that the current time is: 2017-03-22:01:00:00
- this.periodDomains = [
- // last 7 days (whole days)
- ['&', ["date_field", ">=", "2017-03-15"],["date_field", "<", "2017-03-22"]],
- // last 30 days
- ['&', ["date_field", ">=", "2017-02-20"],["date_field", "<", "2017-03-22"]],
- // last 365 days
- ['&', ["date_field", ">=", "2016-03-22"],["date_field", "<", "2017-03-22"]],
- // last 5 years
- ['&', ["date_field", ">=", "2012-03-22"],["date_field", "<", "2017-03-22"]],
- // today
- ['&', ["date_field", ">=", "2017-03-22"],["date_field", "<", "2017-03-23"]],
- // this week
- ['&', ["date_field", ">=", "2017-03-20"],["date_field", "<", "2017-03-27"]],
- // this month
- ['&', ["date_field", ">=", "2017-03-01"],["date_field", "<", "2017-04-01"]],
- // this quarter
- ['&', ["date_field", ">=", "2017-01-01"],["date_field", "<", "2017-04-01"]],
- // this year
- ['&', ["date_field", ">=", "2017-01-01"],["date_field", "<", "2018-01-01"]],
- // yesterday
- ['&', ["date_field", ">=", "2017-03-21"],["date_field", "<", "2017-03-22"]],
- // last week
- ['&', ["date_field", ">=", "2017-03-13"],["date_field", "<", "2017-03-20"]],
- // last month
- ['&', ["date_field", ">=", "2017-02-01"],["date_field", "<", "2017-03-01"]],
- // last quarter
- ['&', ["date_field", ">=", "2016-10-01"],["date_field", "<", "2017-01-01"]],
- // last year
- ['&', ["date_field", ">=", "2016-01-01"],["date_field", "<", "2017-01-01"]],
- ];
-
- this.basicDomains = [
- ["&",["date_field",">=","2017-03-01"],["date_field","<=","2017-03-31"]],
- ["&",["date_field",">=","2017-01-01"],["date_field","<=","2017-12-31"]],
- ["&",["date_field",">=","2017-02-01"],["date_field","<=","2017-02-28"]],
- ["&",["date_field",">=","2017-01-01"],["date_field","<=","2017-12-31"]],
- ["&",["date_field",">=","2017-01-01"],["date_field","<=","2017-01-31"]],
- ["|",
- "&",["date_field",">=","2017-01-01"],["date_field","<=","2017-01-31"],
- "&",["date_field",">=","2017-10-01"],["date_field","<=","2017-12-31"]
- ],
- ["&",["date_field",">=","2017-10-01"],["date_field","<=","2017-12-31"]],
- ["&",["date_field",">=","2017-01-01"],["date_field","<=","2017-12-31"]],
- ["&",["date_field",">=","2017-01-01"],["date_field","<=","2017-03-31"]],
- ["&",["date_field",">=","2017-01-01"],["date_field","<=","2017-12-31"]],
- ["&",["date_field",">=","2017-01-01"],["date_field","<=","2017-12-31"]],
- ["|",
- "&",["date_field",">=","2017-01-01"],["date_field","<=","2017-12-31"],
- "&",["date_field",">=","2016-01-01"],["date_field","<=","2016-12-31"]
- ],
- ["|",
- "|",
- "&",["date_field",">=","2017-01-01"],["date_field","<=","2017-12-31"],
- "&",["date_field",">=","2016-01-01"],["date_field","<=","2016-12-31"],
- "&",["date_field",">=","2015-01-01"],["date_field","<=","2015-12-31"]
- ],
- ["|",
- "|",
- "&", ["date_field",">=","2017-03-01"],["date_field","<=","2017-03-31"],
- "&",["date_field",">=","2016-03-01"],["date_field","<=","2016-03-31"],
- "&",["date_field",">=","2015-03-01"],["date_field","<=","2015-03-31"]
- ]
- ];
-
- // assuming that the current time is: 2017-03-22:01:00:00
- this.previousPeriodDomains = [
- // last 7 days (whole days) - 1 week
- ['&', ["date_field", ">=", "2017-03-08"],["date_field", "<", "2017-03-15"]],
- // last 30 days - 30 days
- ['&', ["date_field", ">=", "2017-01-21"],["date_field", "<", "2017-02-20"]],
- // last 365 days
- ['&', ["date_field", ">=", "2015-03-23"],["date_field", "<", "2016-03-22"]],
- // last 5 years
- ['&', ["date_field", ">=", "2007-03-22"],["date_field", "<", "2012-03-22"]],
- // today - 1 day
- ['&', ["date_field", ">=", "2017-03-21"],["date_field", "<", "2017-03-22"]],
- // this week - 1 week
- ['&', ["date_field", ">=", "2017-03-13"],["date_field", "<", "2017-03-20"]],
- // this month - 1 month
- ['&', ["date_field", ">=", "2017-02-01"],["date_field", "<", "2017-03-01"]],
- // this quarter - 3 months
- ['&', ["date_field", ">=", "2016-10-01"],["date_field", "<", "2017-01-01"]],
- // this year - 1 year
- ['&', ["date_field", ">=", "2016-01-01"],["date_field", "<", "2017-01-01"]],
- // yesterday - 1 day
- ['&', ["date_field", ">=", "2017-03-20"],["date_field", "<", "2017-03-21"]],
- // last week - 1 week
- ['&', ["date_field", ">=", "2017-03-06"],["date_field", "<", "2017-03-13"]],
- // last month - 1 month
- ['&', ["date_field", ">=", "2017-01-01"],["date_field", "<", "2017-02-01"]],
- // last quarter - 3 months
- ['&', ["date_field", ">=", "2016-07-01"],["date_field", "<", "2016-10-01"]],
- // last year - 1 year
- ['&', ["date_field", ">=", "2015-01-01"],["date_field", "<", "2016-01-01"]],
- ];
- },
-}, function () {
- QUnit.test('basic rendering', async function (assert) {
- assert.expect(1);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
- await actionManager.doAction(1);
-
- assert.strictEqual($('.o_searchview input.o_searchview_input')[0], document.activeElement,
- "searchview input should be focused");
-
- actionManager.destroy();
- });
- QUnit.test('navigation with facets', async function (assert) {
- assert.expect(4);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
- await actionManager.doAction(1);
-
- // add a facet
- await testUtils.dom.click(actionManager.$('.o_dropdown_toggler_btn:contains(Group By)'));
- await testUtils.dom.click(actionManager.$('.o_menu_item a'));
- assert.strictEqual(actionManager.$('.o_searchview .o_searchview_facet').length, 1,
- "there should be one facet");
- assert.strictEqual(actionManager.$('.o_searchview input.o_searchview_input')[0], document.activeElement,
- "searchview input should be focused");
-
- // press left to focus the facet
- actionManager.$('.o_searchview_input_container').trigger($.Event('keydown', {
- which: $.ui.keyCode.LEFT,
- keyCode: $.ui.keyCode.LEFT,
- }));
- assert.strictEqual(actionManager.$('.o_searchview .o_searchview_facet')[0], document.activeElement,
- "the facet should be focused");
-
- // press right to focus the facet
- actionManager.$('.o_searchview_input_container').trigger($.Event('keydown', {
- which: $.ui.keyCode.RIGHT,
- keyCode: $.ui.keyCode.RIGHT,
- }));
- assert.strictEqual(actionManager.$('.o_searchview input.o_searchview_input')[0], document.activeElement,
- "searchview input should be focused");
-
- actionManager.destroy();
- });
-
- QUnit.test('default groupbys can be ordered', async function (assert) {
- assert.expect(7);
-
- const unpatchDate = patchDate(2019,6,31,13,43,0);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
-
- this.archs['partner,5,search'] =
- '<search>'+
- '<field name="bar"/>' +
- '<filter string="Foo" name="foo" domain="[]" />' +
- '<filter string="Foo 2" name="foo_2" domain="[]" />' +
- '<filter string="Filter Date Field" name="date" date="date_field"/>' +
- '<filter string="Groupby Date Field Day" name="gb_day" context="{\'group_by\': \'date_field:day\'}"/>' +
- '<filter string="Groupby Foo" name="gb_foo" context="{\'group_by\': \'foo\'}"/>' +
- '<filter string="Groupby Bar" name="gb_bar" context="{\'group_by\': \'bar\'}"/>' +
- '</search>';
- this.actions[0].views = [[false, 'graph']],
- this.actions[0].search_view_id = [5, 'search'];
- this.actions[0].context = {
- search_default_foo: true,
- search_default_date: true,
- search_default_bar: 3,
- search_default_gb_foo: 1,
- search_default_gb_day: 5,
- search_default_gb_bar: true,
- time_ranges: {field: 'date_field', range: 'this_week'},
- };
- await actionManager.doAction(1);
-
- const $facetValues = $('.o_searchview .o_searchview_facet .o_facet_values span:not(.o_facet_values_sep)');
- const expectedLabels = [
- "Third record",
- "Foo",
- "Filter Date Field: July 2019",
- "Groupby Foo",
- "Groupby Date Field Day: Day",
- "Groupby Bar",
- "Date: This Week"
- ];
-
- for (let i = 0; i < expectedLabels.length; i++) {
- assert.strictEqual($facetValues.eq(i).text(), expectedLabels[i],
- `first facet value should be ${expectedLabels[i]}`);
- }
- actionManager.destroy();
- unpatchDate();
- });
-
- QUnit.module('GroupByMenu');
-
- QUnit.test('click on groupby filter adds a facet', async function (assert) {
- assert.expect(1);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
-
- await actionManager.doAction(1);
- await testUtils.dom.click($('.o_dropdown_toggler_btn:contains(Group By)'));
- await testUtils.dom.click($('.o_menu_item a'));
- assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').text().trim(), 'candle',
- 'should have a facet with candle name');
-
- actionManager.destroy();
- });
-
- QUnit.test('remove a "Group By" facet properly unchecks groupbys in groupby menu', async function (assert) {
- assert.expect(2);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
-
- await actionManager.doAction(1);
- await testUtils.dom.click($('.o_dropdown_toggler_btn:contains(Group By)'));
- await testUtils.dom.click($('.o_menu_item a'));
- assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').text().trim(), 'candle',
- 'should have a facet with candle name');
- await testUtils.dom.click($('.o_facet_remove:first'));
- assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').length, 0,
- 'there should be no facet');
- actionManager.destroy();
- });
-
- QUnit.test('change option of a "Group By" does not remove groupy in facet "Group By"', async function (assert) {
- assert.expect(3);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
-
- await actionManager.doAction(2);
- await testUtils.dom.click($('span.fa-bars'));
- await testUtils.dom.click($('.o_submenu_switcher'));
- // Don't forget there is a hidden li.divider element at first place among children
- await testUtils.dom.click($('.o_item_option:nth-child(2)'));
- assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').length, 1,
- 'should have a facet');
- await testUtils.dom.click($('.o_item_option:nth-child(3)'));
- assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').length, 3,
- 'should have three facet spans (two options and a separator between them)');
- await testUtils.dom.click($('.o_item_option:nth-child(2)'));
- await testUtils.dom.click($('.o_item_option:nth-child(3)'));
- assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').length, 0,
- 'should have no facet');
- actionManager.destroy();
- });
-
- QUnit.test('select and unselect quickly groupby does not crash', async function (assert) {
- assert.expect(1);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
-
- await actionManager.doAction(3);
- await testUtils.dom.click($('span.fa-bars'));
- await testUtils.dom.click($('.o_menu_item:first'));
- await testUtils.dom.click($('.o_menu_item:first'));
- assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').length, 0,
- 'should have a facet');
- actionManager.destroy();
- });
-
- QUnit.test('groupby selected within graph subview are not deleted when modifying search view content', async function (assert) {
- assert.expect(2);
-
- this.actions[3].flags = {isEmbedded: true};
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
- await actionManager.doAction(4);
- await testUtils.dom.click($('.o_graph_controller .o_control_panel .o_cp_buttons button').eq(1));
- await testUtils.dom.click($('.o_graph_controller .o_group_by_menu .o_menu_item').eq(1));
- await testUtils.dom.click($('.o_graph_controller .o_group_by_menu .o_menu_item .o_item_option > .dropdown-item').eq(4));
- assert.doesNotHaveClass($('.o_graph_controller .o_group_by_menu .o_menu_item > .dropdown-item').eq(1), 'selected',
- 'groupby should be unselected');
- await testUtils.dom.click($('.o_search_options button span.fa-filter'));
- await testUtils.dom.click($('.o_filters_menu .o_menu_item a').first());
- await testUtils.dom.click($('.o_graph_controller .o_control_panel .o_cp_buttons button').eq(1));
- await testUtils.dom.click($('.o_graph_controller .o_group_by_menu .o_menu_item').eq(1));
- assert.doesNotHaveClass($('.o_graph_controller .o_group_by_menu .o_menu_item > .dropdown-item').eq(1), 'selected',
- 'groupby should be still unselected');
- actionManager.destroy();
- });
-
- QUnit.test('group by a date field using interval works', async function (assert) {
- assert.expect(13);
-
-
- var groupbys = [
- ["date_field:day"],
- ["date_field:month"],
- ["birthday:month"],
- ["birthday:year"],
- ];
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- mockRPC: function (route, args) {
- if (route === '/web/dataset/call_kw/partner/web_read_group') {
- assert.deepEqual(args.kwargs.groupby, groupbys.shift());
- }
- return this._super.apply(this, arguments);
- },
- });
-
- await actionManager.doAction(5);
- // open menu 'Group By'
- await testUtils.dom.click($('.o_search_options .fa-bars'));
- // Open the groupby 'Date'
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item'));
- // select option 'day'
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item .o_item_option[data-option_id="day"]'));
- assert.strictEqual($('div.o_facet_values span').text().trim(),'Date: Day');
- assert.strictEqual($('.o_content tr.o_group_header').length, 5);
- // select option 'month'
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item .o_item_option[data-option_id="day"]'));
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item .o_item_option[data-option_id="month"]'));
- // data should be grouped by the field 'Date' using the interval 'month'
- assert.strictEqual($('div.o_facet_values span').text().trim(),'Date: Month');
- assert.strictEqual($('.o_content tr.o_group_header').length, 3);
- // deactivate option 'month'
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item .o_item_option[data-option_id="month"]'));
- // no groupby is applied
- assert.strictEqual($('div.o_facet_values span').length, 0);
- // open 'Add custom Groupby' menu
- await testUtils.dom.click($('.o_group_by_menu .o_add_custom_group'));
- // click on 'Apply' button
- await testUtils.dom.click($('.o_group_by_menu .o_generator_menu button'));
- // data should be grouped by the field 'Birthday' using the interval 'month'
- assert.strictEqual($('div.o_facet_values span').text().trim(),'Birthday: Month');
- assert.strictEqual($('.o_content tr.o_group_header').length, 5);
- // close first submenu
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item .o_submenu_switcher').eq(0));
- // open submenu with interval options
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item .o_submenu_switcher').eq(1));
- // deselect option 'month'
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item .o_item_option[data-option_id="month"]'));
- // select option 'year'
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item .o_item_option').eq(0));
- // data should be grouped by the field 'Birthday' using the interval 'year'
- assert.strictEqual($('div.o_facet_values span').text().trim(),'Birthday: Year');
- assert.strictEqual($('.o_content tr.o_group_header').length, 4);
-
- actionManager.destroy();
- });
-
- QUnit.test('group by a date field using interval works', async function (assert) {
- assert.expect(8);
-
- var pivot = await createView({
- View: GraphView,
- model: "partner",
- groupBy:['bar'],
- data: this.data,
- arch: '<graph/>',
- archs: {
- 'partner,false,search': `<search>
- <filter string="Bar" name="superName" context="{'group_by': 'bar'}"/>
- <filter string="Date" name="coolName" context="{'group_by': 'date_field'}"/>
- <filter string="Foo" name="superName" context="{'group_by': 'foo'}"/>
- </search>`
- },
- });
-
- function getFacetTexts() {
- return [...pivot.el.querySelectorAll('div.o_facet_values span')].map(
- e => e.innerText
- ).join(' ');
- };
-
- // open menu 'Group By'
- await testUtils.dom.click(pivot.el.querySelector('.o_search_options .fa-bars'));
- // select 'Bar'
- await testUtils.dom.click(pivot.el.querySelectorAll('.o_group_by_menu .o_menu_item')[0]);
- assert.strictEqual(getFacetTexts(), 'Bar');
-
- // Open the groupby 'Date'
- await testUtils.dom.click(pivot.el.querySelectorAll('.o_group_by_menu .o_menu_item')[1]);
- // select option 'week'
- await testUtils.dom.click(pivot.el.querySelector('.o_group_by_menu .o_menu_item .o_item_option[data-option_id="week"]'));
- assert.strictEqual(getFacetTexts(), 'Bar > Date: Week');
-
- // select option 'day'
- await testUtils.dom.click(pivot.el.querySelector('.o_group_by_menu .o_menu_item .o_item_option[data-option_id="day"]'));
- assert.strictEqual(getFacetTexts(), 'Bar > Date: Week > Date: Day');
-
- // select option 'year'
- await testUtils.dom.click(pivot.el.querySelector('.o_group_by_menu .o_menu_item .o_item_option[data-option_id="year"]'));
- assert.strictEqual(getFacetTexts(), 'Bar > Date: Year > Date: Week > Date: Day');
-
- // select 'Foo'
- await testUtils.dom.click(pivot.el.querySelectorAll('.o_group_by_menu .o_menu_item')[2]);
- assert.strictEqual(getFacetTexts(), 'Bar > Date: Year > Date: Week > Date: Day > Foo');
-
- // select option 'quarter'
- await testUtils.dom.click(pivot.el.querySelector('.o_group_by_menu .o_menu_item .o_item_option[data-option_id="quarter"]'));
- assert.strictEqual(getFacetTexts(), 'Bar > Date: Year > Date: Quarter > Date: Week > Date: Day > Foo');
-
- // unselect 'Bar'
- await testUtils.dom.click(pivot.el.querySelectorAll('.o_group_by_menu .o_menu_item')[0]);
- assert.strictEqual(getFacetTexts(), 'Date: Year > Date: Quarter > Date: Week > Date: Day > Foo');
-
- // unselect option 'week'
- await testUtils.dom.click(pivot.el.querySelector('.o_group_by_menu .o_menu_item .o_item_option[data-option_id="week"]'));
- assert.strictEqual(getFacetTexts(), 'Date: Year > Date: Quarter > Date: Day > Foo');
-
- pivot.destroy();
- });
-
- QUnit.test('a separator in groupbys does not cause problems', async function (assert) {
- assert.expect(6);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
-
- await actionManager.doAction(7);
- // open menu 'Group By'
- await testUtils.dom.click($('span.fa-bars'));
- // open options menu
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item a:first'));
- // activate groupby with 'day' option
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item .o_item_option[data-option_id="day"]'));
- // activate the second groupby
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item > a').eq(1));
- assert.strictEqual($('.o_group_by_menu .o_menu_item').length, 2);
- assert.strictEqual($('.o_group_by_menu .o_menu_item > .dropdown-item.selected').length, 2);
- // deactivate second groupby
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item > a').eq(1));
- assert.hasClass($('.o_group_by_menu .o_menu_item > .dropdown-item').eq(0), 'selected');
- assert.doesNotHaveClass($('.o_group_by_menu .o_menu_item > .dropdown-item').eq(1), 'selected');
- // remove facet
- await testUtils.dom.click($('.o_facet_remove'));
- assert.doesNotHaveClass($('.o_group_by_menu .o_menu_item > .dropdown-item').eq(0), 'selected');
- assert.doesNotHaveClass($('.o_group_by_menu .o_menu_item > .dropdown-item').eq(1), 'selected');
- actionManager.destroy();
- });
-
- QUnit.module('FilterMenu');
-
- QUnit.test('Search date and datetime fields. Support of timezones', async function (assert) {
- assert.expect(4);
-
- this.data.partner.fields.birth_datetime = {string: "Birth DateTime", type: "datetime", store: true, sortable: true};
- this.data.partner.records = this.data.partner.records.slice(0,-1); // exclude wrong date record
-
- async function stringToEvent ($element, string) {
- for (var i = 0; i < string.length; i++) {
- var keyAscii = string.charCodeAt(i);
- $element.val($element.val()+string[i]);
- await testUtils.nextTick();
- $element.trigger($.Event('keyup', {which: keyAscii, keyCode:keyAscii}));
- await testUtils.nextTick();
- }
- }
-
- var searchReadSequence = 0;
- var actionManager = await createActionManager({
- actions: [{
- id: 11,
- name: 'Partners Action 11',
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[3, 'list']],
- search_view_id: [9, 'search'],
- }],
- archs: {
- 'partner,3,list': '<tree>' +
- '<field name="foo"/>' +
- '<field name="birthday" />' +
- '<field name="birth_datetime" />' +
- '</tree>',
-
- 'partner,9,search': '<search>'+
- '<field name="birthday"/>' +
- '<field name="birth_datetime" />' +
- '</search>',
- },
- data: this.data,
- session: {
- getTZOffset: function() {
- return 360;
- }
- },
- mockRPC: function (route, args) {
- if (route === '/web/dataset/search_read') {
- if (searchReadSequence === 1) { // The 0th time is at loading
- assert.deepEqual(args.domain, [["birthday", "=", "1983-07-15"]],
- 'A date should stay what the user has input, but transmitted in server\'s format');
- } else if (searchReadSequence === 3) { // the 2nd time is at closing the first facet
- assert.deepEqual(args.domain, [["birth_datetime", "=", "1983-07-14 18:00:00"]],
- 'A datetime should be transformed in UTC and transmitted in server\'s format');
- }
- searchReadSequence+=1;
- }
- return this._super.apply(this, arguments);
- },
- });
-
- await actionManager.doAction(11);
-
- // Date case
- var $autocomplete = $('.o_searchview_input');
- await stringToEvent($autocomplete, '07/15/1983');
- await testUtils.fields.triggerKey('up', $autocomplete, 'enter');
-
- assert.equal($('.o_searchview_facet .o_facet_values').text().trim(), '07/15/1983',
- 'The format of the date in the facet should be in locale');
-
- // Close Facet
- await testUtils.dom.click($('.o_searchview_facet .o_facet_remove'));
-
- // DateTime case
- $autocomplete = $('.o_searchview_input');
- await stringToEvent($autocomplete, '07/15/1983 00:00:00');
- await testUtils.fields.triggerKey('down', $autocomplete, 'down');
- await testUtils.fields.triggerKey('up', $autocomplete, 'enter');
-
- assert.equal($('.o_searchview_facet .o_facet_values').text().trim(), '07/15/1983 00:00:00',
- 'The format of the datetime in the facet should be in locale');
-
- actionManager.destroy();
- });
-
- QUnit.test('add a custom filter works', async function (assert) {
- assert.expect(1);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
-
- await actionManager.doAction(1);
- await testUtils.dom.click($('span.fa-filter'));
- await testUtils.dom.click($('.o_add_custom_filter'));
- await testUtils.dom.click($('.o_apply_filter'));
- assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').text().trim(), 'ID is \"0\"',
- 'should have a facet with candle name');
- actionManager.destroy();
- });
-
- QUnit.test('deactivate a new custom filter works', async function (assert) {
- assert.expect(1);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
-
- await actionManager.doAction(1);
- await testUtils.dom.click($('span.fa-filter'));
- await testUtils.dom.click($('.o_add_custom_filter'));
- await testUtils.dom.click($('.o_apply_filter'));
- await testUtils.dom.click($('.o_menu_item'));
- assert.strictEqual($('.o_searchview .o_searchview_facet .o_facet_values span').length, 0,
- 'no facet should be in the search view');
- actionManager.destroy();
- });
-
- QUnit.test('filter by a date field using period works', async function (assert) {
- assert.expect(15);
-
- var self = this;
-
- this.archs['partner,4,search'] = '<search>'+
- '<filter string="AAA" name="some_filter" date="date_field"></filter>' +
- '</search>';
-
- var unpatchDate = patchDate(2017,2,22,1,0,0);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- mockRPC: function(route, args) {
- if (route === '/web/dataset/search_read' && args.domain.length) {
- assert.deepEqual(args.domain, self.basicDomains.shift());
- }
- return this._super.apply(this, arguments);
- },
- });
-
- await actionManager.doAction(5);
-
- // open menu 'Filter'
- await testUtils.dom.click($('.o_search_options .fa-filter'));
- // open menu options
- await testUtils.dom.click($('.o_menu_item'));
-
- var generatorIds = $('.o_menu_item .o_item_option')
- .map(function() {return $(this).data('option_id');})
- .toArray();
-
- assert.deepEqual(generatorIds, OPTION_GENERATOR_IDS,
- "10 basic period options should be available:");
-
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="this_month"]'));
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="this_month"]'));
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="last_month"]'));
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="last_month"]'));
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="antepenultimate_month"]'));
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="fourth_quarter"]'));
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="antepenultimate_month"]'));
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="fourth_quarter"]'));
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="first_quarter"]'));
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="first_quarter"]'));
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="this_year"]'));
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="this_year"]'));
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="last_year"]'));
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="antepenultimate_year"]'));
- await testUtils.dom.click($('.o_menu_item .o_item_option[data-option_id="this_month"]'));
- actionManager.destroy();
- unpatchDate();
- });
-
- QUnit.test('filter by a date field using period works even in January', async function (assert) {
- assert.expect(3);
-
- this.archs['partner,4,search'] = '<search>'+
- '<filter string="AAA" name="some_filter" date="date_field" default_period="last_month"></filter>' +
- '</search>';
-
- var unpatchDate = patchDate(2017,0,7,3,0,0);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- mockRPC: function(route, args) {
- if (route === '/web/dataset/search_read' && args.domain.length) {
- assert.deepEqual(args.domain,
- ['&', ["date_field", ">=", "2016-12-01"], ["date_field", "<=", "2016-12-31"]]
- );
- }
- return this._super.apply(this, arguments);
- },
- });
-
- this.actions[4].context = {search_default_some_filter: true};
-
- await actionManager.doAction(5);
-
- // open menu 'Filter'
- await testUtils.dom.click($('.o_search_options .fa-filter'));
- // open menu options
- await testUtils.dom.click($('.o_menu_item'));
-
- assert.hasClass($('.o_item_option[data-option_id="last_month"] a'), 'selected');
- assert.hasClass($('.o_item_option[data-option_id="last_year"] a'), 'selected');
-
- actionManager.destroy();
- unpatchDate();
- });
-
- QUnit.test('`context` key in <filter> is used', async function (assert) {
- assert.expect(3);
-
- this.archs['partner,4,search'] = '<search>'+
- '<filter string="AAA" name="some_filter" context="{\'coucou_1\': 1}"></filter>' +
- '</search>';
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- mockRPC: function (route, args) {
- if (route === '/web/dataset/search_read') {
- assert.step(JSON.stringify(args.context));
- }
- return this._super.apply(this, arguments);
- },
- });
-
- await actionManager.doAction(5);
-
- // select filter
- await testUtils.dom.click($('.o_search_options .fa-filter'));
- await testUtils.dom.click($('.o_menu_item:contains(AAA)'));
-
- assert.verifySteps([
- "{\"bin_size\":true}",
- "{\"coucou_1\":1,\"bin_size\":true}",
- ]);
-
- actionManager.destroy();
- });
-
- QUnit.test('Filter with JSON-parsable domain works', async function (assert) {
- assert.expect(1);
-
- var domain = [['foo' ,'=', 'Gently Weeps']];
- var xml_domain = JSON.stringify(domain);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- mockRPC: function (route, args) {
- if (route === '/web/dataset/search_read') {
- assert.deepEqual(args.domain, domain,
- 'A JSON parsable xml domain should be handled just like any other');
- }
- return this._super.apply(this, arguments);
- }
- });
-
- this.archs['partner,5,search'] =
- '<search>'+
- '<filter string="Foo" name="gently_weeps" domain="' + _.escape(xml_domain) + '" />' +
- '</search>';
- this.actions[0].search_view_id = [5, 'search'];
- this.actions[0].context = {search_default_gently_weeps: true};
-
- await actionManager.doAction(1);
-
- actionManager.destroy();
- });
-
- QUnit.test('filter with date attribute set as search_default', async function (assert) {
- assert.expect(1);
-
- const unpatchDate = patchDate(2019,6,31,13,43,0);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
-
- this.archs['partner,5,search'] =
- '<search>'+
- '<filter string="Date" name="date_field" date="date_field" />' +
- '</search>';
- this.actions[0].search_view_id = [5, 'search'];
- this.actions[0].context = {search_default_date_field: true};
-
- await actionManager.doAction(1);
-
- assert.strictEqual($('.o_searchview_input_container .o_facet_values').eq(0).text().trim(),
- "Date: July 2019",
- "There should be a filter facet with label 'Date: July 2019'");
-
- actionManager.destroy();
- unpatchDate();
- });
-
- QUnit.test('Custom Filter datetime with equal operator', async function (assert) {
- assert.expect(5);
-
- this.data.partner.fields.date_time_field = {string: "DateTime", type: "datetime", store: true, searchable: true};
-
- var searchReadCount = 0;
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- session: {
- getTZOffset: function () {
- return -240;
- },
- },
- mockRPC: async function (route, args) {
- if (route === '/web/dataset/search_read') {
- if (searchReadCount === 1) {
- assert.deepEqual(args.domain,
- [['date_time_field', '=', '2017-02-22 15:00:00']], // In UTC
- 'domain is correct'
- );
- }
- }
- return this._super.apply(this, arguments);
- },
- });
- // List view
- await actionManager.doAction(2);
-
- await testUtils.dom.click($('button:contains(Filters)'));
- await testUtils.dom.click($('.o_dropdown_menu .o_add_custom_filter'));
- assert.strictEqual($('.o_dropdown_menu select.o_searchview_extended_prop_field').val(), 'date_time_field',
- 'the date_time_field should be selected in the custom filter');
-
- assert.strictEqual($('.o_dropdown_menu select.o_searchview_extended_prop_op').val(), 'between',
- 'The between operator is selected');
-
- await testUtils.fields.editSelect($('.o_dropdown_menu select.o_searchview_extended_prop_op'), '=');
-
- assert.strictEqual($('.o_dropdown_menu select.o_searchview_extended_prop_op').val(), '=',
- 'The equal operator is selected');
-
- await testUtils.fields.editAndTrigger($('.o_searchview_extended_prop_value input:first'), '02/22/2017 11:00:00', ['change']); // in TZ
-
- searchReadCount = 1;
- await testUtils.dom.click($('.o_dropdown_menu .o_apply_filter'));
-
- assert.strictEqual($('.o_dropdown_menu .dropdown-item.selected').text().trim(), 'DateTime is equal to "02/22/2017 11:00:00"',
- 'Label of Filter is correct');
-
- actionManager.destroy();
- });
-
- QUnit.test('Custom Filter datetime between operator', async function (assert) {
- assert.expect(4);
-
- this.data.partner.fields.date_time_field = {string: "DateTime", type: "datetime", store: true, searchable: true};
-
- var searchReadCount = 0;
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- session: {
- getTZOffset: function () {
- return -240;
- },
- },
- mockRPC: async function (route, args) {
- if (route === '/web/dataset/search_read') {
- if (searchReadCount === 1) {
- assert.deepEqual(args.domain,
- [
- '&', ['date_time_field', '>=', '2017-02-22 15:00:00'], ['date_time_field', '<=', '2017-02-22 21:00:00'] // In UTC
- ],
- 'domain is correct'
- );
- }
- }
- return this._super.apply(this, arguments);
- },
- });
- // List view
- await actionManager.doAction(2);
-
- await testUtils.dom.click($('button:contains(Filters)'));
- await testUtils.dom.click($('.o_dropdown_menu .o_add_custom_filter'));
- assert.strictEqual($('.o_dropdown_menu select.o_searchview_extended_prop_field').val(), 'date_time_field',
- 'the date_time_field should be selected in the custom filter');
-
- assert.strictEqual($('.o_dropdown_menu select.o_searchview_extended_prop_op').val(), 'between',
- 'The between operator is selected');
-
- await testUtils.fields.editAndTrigger($('.o_searchview_extended_prop_value input:first'), '02/22/2017 11:00:00', ['change']); // in TZ
- await testUtils.fields.editAndTrigger($('.o_searchview_extended_prop_value input:last'), '02/22/2017 17:00:00', ['change']); // in TZ
-
- searchReadCount = 1;
- await testUtils.dom.click($('.o_dropdown_menu .o_apply_filter'));
-
- assert.strictEqual($('.o_dropdown_menu .dropdown-item.selected').text().trim(), 'DateTime is between "02/22/2017 11:00:00 and 02/22/2017 17:00:00"',
- 'Label of Filter is correct');
-
- actionManager.destroy();
- });
-
- QUnit.module('Favorites Menu');
-
- QUnit.test('dynamic filters are saved dynamic', async function (assert) {
- assert.expect(1);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- intercepts: {
- create_filter: function (ev) {
- assert.equal(
- ev.data.filter.domain,
- `[("date_field", ">=", (context_today() + relativedelta()).strftime("%Y-%m-%d"))]`);
- },
- },
- });
-
- await actionManager.doAction(12);
- await testUtils.dom.click($('span.fa-filter'));
- await testUtils.dom.click($('.o_filters_menu .o_menu_item a'));
- await testUtils.dom.click($('span.fa-star'));
- await testUtils.dom.click($('.o_favorites_menu .o_add_favorite'));
- await testUtils.fields.editInput($('div.o_favorite_name input'), 'name for favorite');
- await testUtils.dom.click($('.o_favorites_menu .o_save_favorite button'));
- actionManager.destroy();
- });
-
- QUnit.test('save search filter in modal', async function (assert) {
- assert.expect(5);
- this.data.partner.records.push({
- id: 7,
- display_name: "Partner 6",
- }, {
- id: 8,
- display_name: "Partner 7",
- }, {
- id: 9,
- display_name: "Partner 8",
- }, {
- id: 10,
- display_name: "Partner 9",
- });
- this.data.partner.fields.date_field.searchable = true;
- var form = await createView({
- View: FormView,
- model: 'partner',
- data: this.data,
- arch: '<form string="Partners">' +
- '<sheet>' +
- '<group>' +
- '<field name="bar"/>' +
- '</group>' +
- '</sheet>' +
- '</form>',
- archs: {
- 'partner,false,list': '<tree><field name="display_name"/></tree>',
- 'partner,false,search': '<search><field name="date_field"/></search>',
- },
- res_id: 1,
- });
-
- await testUtils.form.clickEdit(form);
-
- await testUtils.fields.many2one.clickOpenDropdown('bar');
- await testUtils.fields.many2one.clickItem('bar','Search');
-
- assert.strictEqual($('tr.o_data_row').length, 9, "should display 9 records");
-
- await testUtils.dom.click($('button:contains(Filters)'));
- await testUtils.dom.click($('.o_add_custom_filter:visible'));
- assert.strictEqual($('.o_filter_condition select.o_searchview_extended_prop_field').val(), 'date_field',
- "date field should be selected");
- await testUtils.dom.click($('.o_apply_filter'));
-
- assert.strictEqual($('tr.o_data_row').length, 0, "should display 0 records");
-
- // Save this search
- await testUtils.mock.intercept(form, 'create_filter', function (event) {
- assert.strictEqual(event.data.filter.name, "Awesome Test Customer Filter", "filter name should be correct");
- });
- await testUtils.dom.click($('button:contains(Favorites)'));
- await testUtils.dom.click($('.o_add_favorite'));
- var filterNameInput = $('.o_favorite_name .o_input[type="text"]:visible');
- assert.strictEqual(filterNameInput.length, 1, "should display an input field for the filter name");
- await testUtils.fields.editInput(filterNameInput, 'Awesome Test Customer Filter');
- await testUtils.dom.click($('.o_save_favorite button'));
-
- form.destroy();
- });
-
- QUnit.test('save filters created via autocompletion works', async function (assert) {
- assert.expect(2);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- intercepts: {
- create_filter: function (ev) {
- assert.ok(ev.data.filter.domain === `[["foo", "ilike", "a"]]`);
- },
- },
- });
-
- await actionManager.doAction(10);
-
- $('.o_searchview_input').trigger($.Event('keypress', {
- which: 97,
- }));
- await testUtils.nextTick();
- $('.o_searchview_input').trigger($.Event('keyup', {
- which: $.ui.keyCode.ENTER,
- keyCode: $.ui.keyCode.ENTER,
- }));
- await testUtils.nextTick();
-
- await testUtils.nextTick();
-
- assert.strictEqual($('.o_searchview_input_container .o_facet_values span').text().trim(), "a");
-
- await testUtils.dom.click($('button .fa-star'));
- await testUtils.dom.click($('.o_favorites_menu .o_add_favorite'));
- await testUtils.fields.editInput($('div.o_favorite_name input'), 'name for favorite');
- await testUtils.dom.click($('.o_favorites_menu div.o_save_favorite button'));
-
- actionManager.destroy();
- });
-
- QUnit.test('delete an active favorite remove it both in list of favorite and in search bar', async function (assert) {
- assert.expect(2);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- intercepts: {
- load_filters: function (event) {
- return Promise.resolve([{
- context: "{}",
- domain: "[]",
- id: 7,
- is_default: true,
- name: "My favorite",
- sort: "[]",
- user_id: [2, "Mitchell Admin"],
- }]).then(event.data.on_success);
- },
- delete_filter: function (event) {
- event.data.on_success();
- }
- },
- });
-
- await actionManager.doAction(6);
- await testUtils.dom.click(actionManager.$('.o_control_panel .o_search_options button.o_favorites_menu_button'));
- assert.containsOnce(actionManager, '.o_control_panel .o_searchview_input_container .o_facet_values');
- await testUtils.dom.click(actionManager.$('.o_control_panel .o_search_options .o_favorites_menu span.o_trash_button'));
- await testUtils.modal.clickButton('Ok');
- assert.containsNone(actionManager, '.o_control_panel .o_searchview_input_container .o_facet_values');
- actionManager.destroy();
- });
-
- QUnit.test('default favorite is not activated if key search_disable_custom_filters is set to true', async function (assert) {
- assert.expect(1);
-
- var controlPanel = await createControlPanel({
- model: 'partner',
- arch: '<controlpanel/>',
- data: this.data,
- intercepts: {
- load_filters: function (event) {
- return Promise.resolve([{
- context: "{}",
- domain: "[]",
- id: 7,
- is_default: true,
- name: "My favorite",
- sort: "[]",
- user_id: [2, "Mitchell Admin"],
- }]).then(event.data.on_success);
- },
- },
- context: {
- search_disable_custom_filters: true,
- },
- });
-
- assert.containsNone(controlPanel, '.o_facet_values');
- controlPanel.destroy();
- });
-
- QUnit.test('toggle favorite correctly clears filter, groupbys and field "options"', async function (assert) {
- assert.expect(8);
-
- const unpatchDate = patchDate(2019,6,31,13,43,0);
-
- const actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- intercepts: {
- load_filters: function (event) {
- return Promise.resolve([{
- context: "{}",
- domain: "[]",
- id: 7,
- is_default: false,
- name: "My favorite",
- sort: "[]",
- user_id: [2, "Mitchell Admin"],
- }]).then(event.data.on_success);
- },
- },
- });
-
- this.actions[11].search_view_id = [10, 'search'];
- await actionManager.doAction(12);
-
- // activate Foo a
- await testUtils.fields.triggerKey('press', $('.o_searchview_input'), 97);
- await testUtils.fields.triggerKey('up', $('.o_searchview_input'), 'enter');
-
- // activate Date Filter with This Month
- await testUtils.dom.click($('button .fa-filter'));
- await testUtils.dom.click($('.o_filters_menu .o_menu_item a'));
- await testUtils.dom.click($('.o_item_option[data-option_id="this_month"]'));
-
- // activate Date Groupby with Year
- await testUtils.dom.click($('button .fa-bars'));
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item a'));
- await testUtils.dom.click($('.o_item_option[data-option_id="year"]'));
-
- assert.strictEqual($('.o_searchview_input_container .o_facet_values').eq(0).text().trim(),
- "a",
- "There should be a filter Foo a");
-
- assert.strictEqual($('.o_searchview_input_container .o_facet_values').eq(1).text().trim(),
- "Date Field Filter: July 2019",
- "There should be a filter facet with label 'Date Field Filter: July 2019'");
-
- assert.strictEqual($('.o_searchview_input_container .o_facet_values').eq(2).text().trim(),
- "Date Field Groupby: Year",
- "There should be a groupby facet with label 'Date Field Groupby: Year'");
-
- // activate the favorite
- await testUtils.dom.click($('button .fa-star'));
- await testUtils.dom.click($('.o_favorites_menu .o_menu_item a'));
-
- assert.containsOnce(actionManager, '.o_searchview_input_container .o_facet_values',
- "There should be a unique facet in the search bar");
- assert.strictEqual($('.o_searchview_input_container .o_facet_values').eq(0).text().trim(),
- "My favorite",
- "There should be a facet with label 'My favorite''");
-
- await testUtils.dom.click($('button .fa-filter'));
- await testUtils.dom.click($('.o_filters_menu .o_menu_item a'));
- assert.doesNotHaveClass($('.o_item_option[data-option_id="this_month"]'), 'selected',
- "The Date Filter option 'This Month' should be deactivated");
-
- await testUtils.dom.click($('button .fa-bars'));
- await testUtils.dom.click($('.o_group_by_menu .o_menu_item a'));
- assert.doesNotHaveClass($('.o_item_option[data-option_id="year"]'), 'selected',
- "The Date Groupby option 'Year' should be deactivated");
-
- await testUtils.fields.triggerKey('press', $('.o_searchview_input'), 98);
- await testUtils.fields.triggerKey('up', $('.o_searchview_input'), 'enter');
- assert.strictEqual($('.o_searchview_input_container .o_facet_values').eq(1).text().trim(),
- "b",
- "There should be a filter Foo b");
-
- actionManager.destroy();
- unpatchDate();
- });
-
- QUnit.test('favorites have unique descriptions (the submenus of the favorite menu are correctly updated)', async function (assert) {
- assert.expect(7);
-
- const UID = session.uid;
-
- const actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- intercepts: {
- load_filters: function (event) {
- return Promise.resolve([{
- context: "{}",
- domain: "[]",
- id: 7,
- is_default: false,
- name: "My favorite",
- sort: "[]",
- user_id: [2, "Mitchell Admin"],
- }]).then(event.data.on_success);
- },
- create_filter: function (event) {
- assert.step('create_filter');
- assert.deepEqual(event.data.filter, {
- "action_id": 1,
- "context": {},
- "domain": "[]",
- "is_default": false,
- "model_id": "partner",
- "name": "My favorite 2",
- "sort": "[]",
- "user_id": UID,
- });
- return Promise.resolve(1).then(event.data.on_success);
- }
- },
- });
- testUtils.mock.intercept(actionManager, 'call_service', function (ev) {
- if (ev.data.service === 'notification') {
- // A notification alerting that another favorite with same name exists
- // should be triggered
- assert.step('notification');
- assert.deepEqual(ev.data.args[0], {
- "className": undefined,
- "message": "Filter with same name already exists.",
- "sticky": undefined,
- "title": "Error",
- "type": "danger"
- });
- }
- }, true);
-
- await actionManager.doAction(1);
- await testUtils.dom.click($('button .fa-star'));
- await testUtils.dom.click($('.o_favorites_menu .o_add_favorite'));
- await testUtils.fields.editInput($('div.o_favorite_name input'), 'My favorite');
- await testUtils.dom.click($('.o_favorites_menu div.o_save_favorite button'));
-
- await testUtils.fields.editInput($('div.o_favorite_name input'), 'My favorite 2');
- await testUtils.dom.click($('.o_favorites_menu div.o_save_favorite button'));
-
- await testUtils.dom.click($('.o_favorites_menu .o_add_favorite'));
- await testUtils.fields.editInput($('div.o_favorite_name input'), 'My favorite 2');
- await testUtils.dom.click($('.o_favorites_menu div.o_save_favorite button'));
-
- assert.verifySteps([
- 'notification',
- 'create_filter',
- 'notification'
- ])
-
- actionManager.destroy();
- });
-
- QUnit.module('Search Arch');
-
- QUnit.test('arch order of groups of filters preserved', async function (assert) {
- assert.expect(12);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
-
- await actionManager.doAction(8);
- await testUtils.dom.click($('span.fa-filter'));
- assert.strictEqual($('.o_filters_menu .o_menu_item').length, 11);
- for (var i = 0; i < 11; i++) {
- assert.strictEqual($('.o_filters_menu .o_menu_item').eq(i).text().trim(), (i+1).toString());
- }
- actionManager.destroy();
- });
-
- QUnit.module('Autocompletion');
-
- QUnit.test('select an autocomplete field', async function (assert) {
- assert.expect(3);
-
- var searchRead = 0;
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- mockRPC: function (route, args) {
- if (route === '/web/dataset/search_read') {
- if (searchRead === 1) {
- assert.deepEqual(args.domain, [["foo", "ilike", "a"]]);
- }
- searchRead++;
- }
- return this._super.apply(this, arguments);
- },
- });
-
- await actionManager.doAction(11);
-
- await testUtils.fields.triggerKey('press', $('.o_searchview_input'), 97);
- assert.strictEqual(actionManager.$('.o_searchview_autocomplete li').length, 2,
- "there should be 2 result for 'a' in search bar autocomplete");
-
- await testUtils.fields.triggerKey('up', $('.o_searchview_input'), 'enter');
- assert.strictEqual($('.o_searchview_input_container .o_facet_values').eq(0).text().trim(),
- "a", "There should be a field facet with label 'a'");
-
- actionManager.destroy();
- });
-
- QUnit.test('select an autocomplete field with `context` key', async function (assert) {
- assert.expect(9);
-
- var searchRead = 0;
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- mockRPC: function (route, args) {
- if (route === '/web/dataset/search_read') {
- if (searchRead === 1) {
- assert.deepEqual(args.domain, [["bar", "=", 1]]);
- assert.deepEqual(args.context.bar, [1]);
- } else if (searchRead === 2) {
- assert.deepEqual(args.domain, ["|", ["bar", "=", 1], ["bar", "=", 2]]);
- assert.deepEqual(args.context.bar, [1, 2]);
- }
- searchRead++;
- }
- return this._super.apply(this, arguments);
- },
- });
-
- await actionManager.doAction(11);
- await testUtils.nextTick();
- assert.strictEqual(searchRead, 1, "there should be 1 search_read");
-
- // 'r' key to filter on bar "First Record"
- $('.o_searchview_input').val('r');
- $('.o_searchview_input').trigger($.Event('keypress', { which: 82, keyCode: 82 }));
- await testUtils.nextTick();
- $('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.DOWN, keyCode: $.ui.keyCode.DOWN }));
- await testUtils.nextTick();
- $('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.RIGHT, keyCode: $.ui.keyCode.RIGHT }));
- await testUtils.nextTick();
- $('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.DOWN, keyCode: $.ui.keyCode.DOWN }));
- await testUtils.nextTick();
- $('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.ENTER, keyCode: $.ui.keyCode.ENTER }));
- await testUtils.nextTick();
-
- await testUtils.nextTick();
- assert.strictEqual($('.o_searchview_input_container .o_facet_values').eq(0).text().trim(), "First record",
- "the autocompletion facet should be correct");
- assert.strictEqual(searchRead, 2, "there should be 2 search_read");
-
- // 'r' key to filter on bar "Second Record"
- $('.o_searchview_input').val('r');
- $('.o_searchview_input').trigger($.Event('keypress', { which: 82, keyCode: 82 }));
- await testUtils.nextTick();
- $('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.DOWN, keyCode: $.ui.keyCode.DOWN }));
- await testUtils.nextTick();
- $('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.RIGHT, keyCode: $.ui.keyCode.RIGHT }));
- await testUtils.nextTick();
- $('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.DOWN, keyCode: $.ui.keyCode.DOWN }));
- await testUtils.nextTick();
- $('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.DOWN, keyCode: $.ui.keyCode.DOWN }));
- $('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.ENTER, keyCode: $.ui.keyCode.ENTER }));
- await testUtils.nextTick();
-
- assert.strictEqual($('.o_searchview_input_container .o_facet_values').eq(0).text().trim(), "First record or Second record",
- "the autocompletion facet should be correct");
- assert.strictEqual(searchRead, 3, "there should be 3 search_read");
-
- actionManager.destroy();
- });
-
- QUnit.test('no search text triggers a reload', async function (assert) {
- assert.expect(2);
- var rpcs = 0;
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- mockRPC: function () {
- rpcs++;
- return this._super.apply(this, arguments);
- },
- });
-
- await actionManager.doAction(10);
- rpcs = 0;
- $('.o_searchview_input').trigger($.Event('keydown', {
- which: $.ui.keyCode.ENTER,
- keyCode: $.ui.keyCode.ENTER,
- }));
- await testUtils.nextTick();
-
- $('.o_searchview_input').trigger($.Event('keyup', {
- which: $.ui.keyCode.ENTER,
- keyCode: $.ui.keyCode.ENTER,
- }));
- await testUtils.nextTick();
-
- assert.containsNone(actionManager, '.o_searchview_facet_label');
- assert.strictEqual(rpcs, 2, "should have reloaded");
-
- actionManager.destroy();
- });
-
- QUnit.test('selecting (no result) triggers a re-render', async function (assert) {
- assert.expect(3);
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
-
- actionManager.doAction(10);
- await testUtils.nextTick();
-
- // 'a' key to filter nothing on bar
- actionManager.$('.o_searchview_input').val('a');
- actionManager.$('.o_searchview_input').trigger($.Event('keypress', { which: 65, keyCode: 65 }));
- await testUtils.nextTick();
- actionManager.$('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.DOWN, keyCode: $.ui.keyCode.DOWN }));
- await testUtils.nextTick();
- actionManager.$('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.RIGHT, keyCode: $.ui.keyCode.RIGHT }));
- await testUtils.nextTick();
- actionManager.$('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.DOWN, keyCode: $.ui.keyCode.DOWN }));
- await testUtils.nextTick();
-
- assert.strictEqual(actionManager.$('.o_searchview_autocomplete .o-selection-focus').text(), "(no result)",
- "there should be no result for 'a' in bar");
-
- actionManager.$('.o_searchview_input').trigger($.Event('keydown', { which: $.ui.keyCode.ENTER, keyCode: $.ui.keyCode.ENTER }));
- await testUtils.nextTick();
-
- assert.containsNone(actionManager, '.o_searchview_facet_label');
- assert.strictEqual(actionManager.$('.o_searchview_input').val(), "",
- "the search input should be re-rendered");
-
- actionManager.destroy();
- });
-
- QUnit.test('update suggested filters in autocomplete menu with Japanese IME', async function (assert) {
- assert.expect(4);
-
- this.actions.push({
- id: 13,
- name: 'Partners Action 11',
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[false, 'list']],
- search_view_id: [13, 'search'],
- });
- this.archs['partner,13,search'] = `
- <search>
- <field name="foo"/>
- <field name="bar"/>
- </search>`;
-
- const actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
- actionManager.doAction(13);
- await testUtils.nextTick();
-
- // Simulate typing "Test" on search view.
- const TEST = "TEST";
- $('.o_searchview_input').val(TEST);
- for (const char of TEST) {
- $('.o_searchview_input').trigger($.Event('keypress', {
- which: char.charCodeAt(0),
- keyCode: char.charCodeAt(0),
- }));
- }
- $('.o_searchview_input').trigger($.Event('keyup'));
- await testUtils.nextTick();
- assert.containsOnce(
- $,
- '.o_searchview_autocomplete',
- "should display autocomplete dropdown menu on typing something in search view"
- );
- assert.strictEqual(
- $('.o_searchview_autocomplete li:first').text(),
- "Search Foo for: TEST",
- `1st filter suggestion should be based on typed word "TEST"`
- );
-
- // Simulate soft-selection of another suggestion from IME.
- const テスト = "テスト";
- $('.o_searchview_input').val(テスト);
- for (const char of テスト) {
- $('.o_searchview_input').trigger($.Event('keypress', {
- which: char.charCodeAt(0),
- keyCode: char.charCodeAt(0),
- }));
- }
- $('.o_searchview_input').trigger($.Event('keyup'));
- await testUtils.nextTick();
- assert.strictEqual(
- $('.o_searchview_autocomplete li:first').text(),
- "Search Foo for: テスト",
- `1st filter suggestion should be updated with soft-selection typed word "テスト"`
- );
-
- // Simulate selection on suggestion item "Test" from IME.
- $('.o_searchview_input').val("TEST");
- const nativeInputEvent = new window.InputEvent('input', { inputType: 'insertCompositionText' });
- const jqueryInputEvent = $.Event('input', { bubbles: true });
- jqueryInputEvent.originalEvent = nativeInputEvent;
- $('.o_searchview_input').trigger(jqueryInputEvent);
- await testUtils.nextTick();
- assert.strictEqual(
- $('.o_searchview_autocomplete li:first').text(),
- "Search Foo for: TEST",
- `1st filter suggestion should finally be updated with click selection on word "TEST" from IME`
- );
-
- actionManager.destroy();
- });
-
- QUnit.module('TimeRangeMenu');
-
- QUnit.test('time range menu stays hidden', async function (assert) {
- assert.expect(4);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- });
-
- await actionManager.doAction(1);
-
- // check that there is no time range menu
- assert.containsNone(actionManager, '.o_control_panel .o_search_options .o_time_range_menu');
- // check if search view has no facets
- assert.strictEqual($('.o_facet_values').length, 0);
-
- // activate groupby
- await testUtils.dom.click($('button .fa-bars'));
- await testUtils.dom.click($('.o_menu_item a').eq(0));
- // check that there is a facet
- assert.strictEqual($('div.o_facet_values').length, 1);
- // check that there is still no time range menu
- assert.containsNone(actionManager, '.o_control_panel .o_search_options .o_time_range_menu');
- actionManager.destroy();
- });
-
- QUnit.test('time range menu in comparison mode', async function (assert) {
- assert.expect(46);
-
- var self = this;
- var nbrReadGroup = 0;
-
- var periodOptionText, periodOptionValue;
- var unpatchDate = patchDate(2017, 2, 22, 1, 0, 0);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- mockRPC: function (route, args) {
- if (route === '/web/dataset/call_kw/partner/read_group') {
- nbrReadGroup++;
- var timeRangeMenuData = args.kwargs.context.timeRangeMenuData;
- if (timeRangeMenuData) {
- // nbrReadGroup % 2 === 0 is true when the read group is for data, false
- // for comparison data
- if (nbrReadGroup % 2 === 0) {
- assert.deepEqual(timeRangeMenuData.timeRange,
- self.periodDomains.shift(),
- "time range domain for " + periodOptionText);
- } else {
- assert.deepEqual(timeRangeMenuData.comparisonTimeRange,
- self.previousPeriodDomains.shift(),
- "comparaison time range domain for " + periodOptionText);
- }
- }
- }
- return this._super.apply(this, arguments);
- },
- });
- // time range menu should be available in graph view
- await actionManager.doAction(4);
-
- var $timeRangeMenu = $('.o_time_range_menu');
- assert.strictEqual($timeRangeMenu.not('.o_hidden').length, 1,
- "Time range menu should be visible");
- assert.strictEqual($('.o_facet_values').length, 0,
- "Search view has no facet");
-
- var $periodOptions = $timeRangeMenu.find('.o_time_range_selector option');
- var periodOptions = $periodOptions.map(function () {
- return $(this).val();
- }).toArray();
- assert.deepEqual(periodOptions, PERIOD_OPTIONS_IDS,
- "13 period options should be available:");
-
- for (var option of $periodOptions) {
- periodOptionText = $(option).text().trim();
- periodOptionValue = $(option).val();
- // opens time range menu dropdown
- await testUtils.dom.click($('.o_time_range_menu_button'));
- var $timeRangeMenu = $('.o_time_range_menu');
- // comparison is not checked by default
- if (!$timeRangeMenu.find('.o_comparison_checkbox').is(':checked')) {
- await testUtils.dom.click($timeRangeMenu.find('.o_comparison_checkbox'));
- assert.strictEqual($('.o_comparison_time_range_selector:visible').length, 1,
- "Comparison has to be checked (only at the first time)");
- }
- // select one period option to test it
- $timeRangeMenu.find('.o_time_range_selector').val(periodOptionValue);
- // apply
- await testUtils.dom.click($timeRangeMenu.find('.o_apply_range'));
- assert.strictEqual($('.o_facet_values').text().trim(),
- "Date: " + periodOptionText + " / Previous Period",
- "Facet should be updated with this period: " + periodOptionValue);
- }
- unpatchDate();
- actionManager.destroy();
- });
-
- QUnit.test('a default time range only in context is taken into account', async function (assert) {
- assert.expect(1);
-
- var actionManager = await createActionManager({
- actions: this.actions,
- archs: this.archs,
- data: this.data,
- mockRPC: function (route, args) {
- // there are only one read_group call (for the groupby lists [])
- // the read group for the list ["date_field:day"] is not done since no data is available for today)
- if (route === '/web/dataset/call_kw/partner/read_group') {
- var timeRangeMenuData = args.kwargs.context.timeRangeMenuData;
- assert.ok(timeRangeMenuData.timeRange.length > 0, "time range should be non empty");
- }
- return this._super.apply(this, arguments);
- },
- });
-
- await actionManager.doAction({
- res_model: 'partner',
- type: 'ir.actions.act_window',
- views: [[false, 'pivot']],
- context: {time_ranges: {range: 'today', field: 'date_field'}}
- });
- actionManager.destroy();
- });
-
- QUnit.test('Customizing filter does not close the filter dropdown', async function (assert) {
- assert.expect(5);
- var self = this;
-
- _.each(this.data.partner.records.slice(), function (rec) {
- var copy = _.defaults({}, rec, {id: rec.id + 10 });
- self.data.partner.records.push(copy);
- });
-
- this.data.partner.fields.date_field.searchable = true;
- var form = await createView({
- View: FormView,
- model: 'partner',
- data: this.data,
- arch: '<form string="Partners">' +
- '<field name="bar"/>' +
- '</form>',
- viewOptions: {
- mode: 'edit',
- },
- archs: {
- 'partner,false,list': '<tree><field name="display_name"/></tree>',
- 'partner,false,search': '<search><field name="date_field"/></search>',
- },
- res_id: 1,
- intercepts: {
- create_filter: function (ev) {
- var data = ev.data;
- assert.strictEqual(data.filter.name, 'Fire on the bayou');
- assert.strictEqual(data.filter.is_default, true);
- },
- },
- });
-
- await testUtils.fields.many2one.clickOpenDropdown('bar');
- await testUtils.fields.many2one.clickItem('bar', 'Search More');
-
- assert.containsOnce(document.body, '.modal');
-
- await testUtils.dom.click($('.modal .o_filters_menu_button'));
-
- var $filterDropdown = $('.modal .o_filters_menu');
- await testUtils.dom.click($filterDropdown.find('.o_add_custom_filter'));
-
- assert.containsN($filterDropdown, '.o_input', 4);
-
- // We really are interested in the click event
- // We do it twice on each input to make sure
- // the parent dropdown doesn't react to any of it
- _.each($filterDropdown.find('input'), async function (input) {
- var $input = $(input);
- $input.click();
- $input.click();
- await testUtils.nextTick();
- });
- assert.isVisible($filterDropdown);
-
- // Favorites Menu
- var $modal = $('.modal');
- await testUtils.dom.click($modal.find('.o_favorites_menu_button'));
- await testUtils.dom.click($modal.find('.o_add_favorite'));
- $modal.find('.o_search_options .dropdown-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.fields.editInput($modal.find('div.o_favorite_name input'), 'Fire on the bayou');
- await testUtils.dom.click($modal.find('.o_add_favorite ~ div label:contains(Use by default)'));
- await testUtils.dom.click($modal.find('.o_save_favorite button'));
-
- form.destroy();
- });
-});
-});
diff --git a/addons/web/static/tests/views/view_dialogs_tests.js b/addons/web/static/tests/views/view_dialogs_tests.js
index 4e205c420a1..e86d0f53297 100644
--- a/addons/web/static/tests/views/view_dialogs_tests.js
+++ b/addons/web/static/tests/views/view_dialogs_tests.js
@@ -7,8 +7,16 @@ var testUtils = require('web.test_utils');
var Widget = require('web.Widget');
var FormView = require('web.FormView');
+const cpHelpers = testUtils.controlPanel;
var createView = testUtils.createView;
+async function createParent(params) {
+ var widget = new Widget();
+ params.server = await testUtils.mock.addMockEnvironment(widget, params);
+ owl.Component.env = testUtils.mock.getMockedOwlEnv(params);
+ return widget;
+}
+
QUnit.module('Views', {
beforeEach: function () {
this.data = {
@@ -56,17 +64,10 @@ QUnit.module('Views', {
QUnit.module('view_dialogs');
- function createParent(params) {
- var widget = new Widget();
-
- testUtils.mock.addMockEnvironment(widget, params);
- return widget;
- }
-
QUnit.test('formviewdialog buttons in footer are positioned properly', async function (assert) {
assert.expect(2);
- var parent = createParent({
+ var parent = await createParent({
data: this.data,
archs: {
'partner,false,form':
@@ -97,7 +98,7 @@ QUnit.module('Views', {
this.data.partner.fields.poney_ids = {string: "Poneys", type: "one2many", relation: 'partner'};
this.data.partner.records[0].poney_ids = [];
- var parent = createParent({
+ var parent = await createParent({
data: this.data,
archs: {
'partner,false,form':
@@ -129,7 +130,7 @@ QUnit.module('Views', {
assert.expect(3);
var search = 0;
- var parent = createParent({
+ var parent = await createParent({
data: this.data,
archs: {
'partner,false,list':
@@ -196,9 +197,8 @@ QUnit.module('Views', {
dialog = result;
});
await testUtils.nextTick();
-
- await testUtils.dom.click(dialog.$('.o_searchview_facet:contains(groupby_bar) .o_facet_remove'));
- await testUtils.dom.click(dialog.$('.o_searchview_facet .o_facet_remove'));
+ await cpHelpers.removeFacet('.modal', "Bar");
+ await cpHelpers.removeFacet('.modal');
parent.destroy();
});
@@ -206,7 +206,7 @@ QUnit.module('Views', {
QUnit.test('SelectCreateDialog correctly evaluates domains', async function (assert) {
assert.expect(1);
- var parent = createParent({
+ var parent = await createParent({
data: this.data,
archs: {
'partner,false,list':
@@ -245,7 +245,7 @@ QUnit.module('Views', {
QUnit.test('SelectCreateDialog list view in readonly', async function (assert) {
assert.expect(1);
- var parent = createParent({
+ var parent = await createParent({
data: this.data,
archs: {
'partner,false,list':
@@ -437,7 +437,7 @@ QUnit.module('Views', {
},
});
- var parent = createParent({
+ var parent = await createParent({
data: this.data,
archs: {
'partner,false,list':
@@ -450,14 +450,19 @@ QUnit.module('Views', {
'</search>',
},
- intercepts: {
- create_filter: function (event) {
- var filter = event.data.filter;
- assert.deepEqual(filter.domain, `[("bar", "=", True)]`,
- "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", "=", True)]`,
+ "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");
+ },
+ }
},
});
@@ -470,19 +475,20 @@ QUnit.module('Views', {
});
await testUtils.nextTick();
+
assert.containsN(dialog, '.o_data_row', 3, "should contain 3 records");
// filter on bar
- await testUtils.dom.click(dialog.$('.o_dropdown_toggler_btn:contains(Filters)'));
- await testUtils.dom.click(dialog.$('.o_filters_menu a:contains(Bar)'));
+ await cpHelpers.toggleFilterMenu('.modal');
+ await cpHelpers.toggleMenuItem('.modal', "Bar");
assert.containsN(dialog, '.o_data_row', 2, "should contain 2 records");
// save filter
- await testUtils.dom.click(dialog.$('.o_dropdown_toggler_btn:contains(Favorites)'));
- await testUtils.dom.click(dialog.$('.o_add_favorite'));
- await testUtils.fields.editInput(dialog.$('.o_favorite_name input[type=text]'), 'some name'); // name the filter
- await testUtils.dom.click(dialog.$('.o_save_favorite button'));
+ await cpHelpers.toggleFavoriteMenu('.modal');
+ await cpHelpers.toggleSaveFavorite('.modal');
+ await cpHelpers.editFavoriteName('.modal', "some name");
+ await cpHelpers.saveFavorite('.modal');
testUtils.mock.unpatch(ListController);
parent.destroy();
@@ -555,7 +561,7 @@ QUnit.module('Views', {
this.data.partner.records[0].poney_ids = [];
var reject = true;
- var parent = createParent({
+ var parent = await createParent({
data: this.data,
archs: {
'partner,false,form':
diff --git a/addons/web/static/tests/widgets/data_export_tests.js b/addons/web/static/tests/widgets/data_export_tests.js
index c9c51219571..2d3488f5891 100644
--- a/addons/web/static/tests/widgets/data_export_tests.js
+++ b/addons/web/static/tests/widgets/data_export_tests.js
@@ -1,12 +1,13 @@
odoo.define('web.data_export_tests', function (require) {
"use strict";
-var framework = require('web.framework');
-var ListView = require('web.ListView');
-var testUtils = require('web.test_utils');
-var data = require('web.data');
+const framework = require('web.framework');
+const ListView = require('web.ListView');
+const testUtils = require('web.test_utils');
+const data = require('web.data');
-var createView = testUtils.createView;
+const cpHelpers = testUtils.controlPanel;
+const createView = testUtils.createView;
QUnit.module('widgets', {
beforeEach: function () {
@@ -63,7 +64,7 @@ QUnit.module('widgets', {
data: this.data,
arch: '<tree><field name="foo"/></tree>',
viewOptions: {
- hasSidebar: true,
+ hasActionMenus: true,
},
mockRPC: function (route) {
if (route === '/web/export/formats') {
@@ -104,9 +105,11 @@ QUnit.module('widgets', {
},
});
+
await testUtils.dom.click(list.$('thead th.o_list_record_selector input'));
- await testUtils.dom.click(list.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(list.sidebar.$('a:contains(Export)'));
+
+ await cpHelpers.toggleActionMenu(list);
+ await cpHelpers.toggleMenuItem(list, 'Export');
assert.strictEqual($('.modal').length, 1, "a modal dialog should be open");
assert.strictEqual($('div.o_tree_column:contains(Activities)').length, 1,
@@ -144,7 +147,7 @@ QUnit.module('widgets', {
data: this.data,
arch: '<tree><field name="foo"/></tree>',
viewOptions: {
- hasSidebar: true,
+ hasActionMenus: true,
},
mockRPC: function (route) {
if (route === '/web/export/formats') {
@@ -179,10 +182,12 @@ QUnit.module('widgets', {
},
});
+
// Open the export modal
await testUtils.dom.click(list.$('thead th.o_list_record_selector input'));
- await testUtils.dom.click(list.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(list.sidebar.$('a:contains(Export)'));
+ await cpHelpers.toggleActionMenu(list);
+ await cpHelpers.toggleMenuItem(list, 'Export');
+
assert.strictEqual($('.modal').length, 1,
"a modal dialog should be open");
@@ -214,7 +219,7 @@ QUnit.module('widgets', {
data: this.data,
arch: '<tree><field name="foo"/></tree>',
viewOptions: {
- hasSidebar: true,
+ hasActionMenus: true,
},
mockRPC: function (route) {
if (route === '/web/export/formats') {
@@ -248,10 +253,12 @@ QUnit.module('widgets', {
return this._super.apply(this, arguments);
},
});
+
+
// Open the export modal
- await testUtils.dom.click(list.$('thead .o_list_record_selector input'));
- await testUtils.dom.click(list.sidebar.$('.o_dropdown_toggler_btn:contains(Action)'));
- await testUtils.dom.click(list.sidebar.$('a:contains(Export)'));
+ await testUtils.dom.click(list.$('thead th.o_list_record_selector input'));
+ await cpHelpers.toggleActionMenu(list);
+ await cpHelpers.toggleMenuItem(list, 'Export');
assert.strictEqual($('.modal .o_export_tree_item:visible').length, 2, "There should be only two items visible");
await testUtils.dom.click($('.modal .o_export_search_input'));
@@ -333,7 +340,6 @@ QUnit.module('widgets', {
View: ListView,
model: 'partner',
data: this.data,
- debug: true,
arch: `
<tree>
<field name="foo"/>
diff --git a/addons/web/static/tests/widgets/dropdown_menu_tests.js b/addons/web/static/tests/widgets/dropdown_menu_tests.js
deleted file mode 100644
index ff53b3d77e8..00000000000
--- a/addons/web/static/tests/widgets/dropdown_menu_tests.js
+++ /dev/null
@@ -1,203 +0,0 @@
-odoo.define('web.dropdown_menu_tests', function (require) {
-"use strict";
-
-var DropdownMenu = require('web.DropdownMenu');
-var testUtils = require('web.test_utils');
-
-function createDropdownMenu(items, params) {
- params = params || {};
- var target = params.debug ? document.body : $('#qunit-fixture');
- var menu = new DropdownMenu(null, items);
- testUtils.mock.addMockEnvironment(menu, params);
- return menu.appendTo(target).then(function() {
- return menu;
- });
-}
-
-QUnit.module('Web', {
- beforeEach: function () {
- this.items = [
- {
- isActive: false,
- description: 'Some Item',
- id: 1,
- groupId: 1,
- groupNumber: 1,
- },
- {
- isActive: true,
- description: 'Some other Item',
- id: 2,
- groupId: 2,
- groupNumber: 2,
- },
- ];
- },
-}, function () {
- QUnit.module('DropdownMenu');
-
- QUnit.test('simple rendering', async function (assert) {
- assert.expect(4);
-
- var dropdownMenu = await createDropdownMenu(this.items);
- assert.containsN(dropdownMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 4,
- 'should have 4 elements counting the dividers');
- assert.strictEqual(dropdownMenu.$('.o_menu_item').first().text().trim(), 'Some Item',
- 'first element should have "Some Item" description');
- assert.ok(!dropdownMenu.$('.o_menu_item > .dropdown-item').eq(0).hasClass('selected'),
- 'first element should not be selected');
- assert.ok(dropdownMenu.$('.o_menu_item > .dropdown-item').eq(1).hasClass('selected'),
- 'second element should be selected');
-
- dropdownMenu.destroy();
- });
-
- QUnit.test('click on an item without options should toggle it', async function (assert) {
- assert.expect(7);
-
- var self = this;
- var dropdownMenu = await createDropdownMenu(this.items, {
- intercepts: {
- menu_item_clicked: function (ev) {
- assert.strictEqual(ev.data.id, 1);
- self.items[0].isActive = !self.items[0].isActive;
- dropdownMenu.update(self.items);
- },
- },
- });
- await testUtils.dom.click(dropdownMenu.$('button:first'));
- assert.doesNotHaveClass(dropdownMenu.$('.o_menu_item:first > .dropdown-item').first(), 'selected');
- await testUtils.dom.click(dropdownMenu.$('.o_menu_item a').first());
- assert.hasClass(dropdownMenu.$('.o_menu_item:first > .dropdown-item'), 'selected');
- assert.ok(dropdownMenu.$('.o_menu_item:first').is(':visible'),
- 'item should still be visible');
- await testUtils.dom.click(dropdownMenu.$('.o_menu_item a').first());
- assert.doesNotHaveClass(dropdownMenu.$('.o_menu_item:first > .dropdown-item').first(), 'selected');
- assert.ok(dropdownMenu.$('.o_menu_item:first').is(':visible'),
- 'item should still be visible');
- dropdownMenu.destroy();
- });
-
- QUnit.test('click on an item should not change url', async function (assert) {
- assert.expect(0);
-
- var dropdownMenu = await createDropdownMenu(this.items);
- await testUtils.dom.click(dropdownMenu.$('.o_dropdown_toggler_btn'));
- dropdownMenu.$el.click(function () {
- // we do not want a click to get out and change the url, for example
- throw new Error('No click should get out of the dropdown menu');
- });
- await testUtils.dom.click(dropdownMenu.$('.o_menu_item a').first());
-
- dropdownMenu.destroy();
- });
-
- QUnit.test('options rendering', async function (assert) {
- assert.expect(3);
-
- this.items[0].hasOptions = true;
- this.items[0].options = [
- {optionId: 1, description: "First Option", groupId: 1},
- {optionId: 2, description: "Second Option", groupId: 1}
- ];
- this.items[0].currentOptionIds = new Set();
- var dropdownMenu = await createDropdownMenu(this.items);
- testUtils.dom.click(dropdownMenu.$('button:first'));
- assert.containsN(dropdownMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 4);
- // open options menu
- await testUtils.dom.click(dropdownMenu.$('span.fa-caret-right'));
- assert.containsN(dropdownMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 7);
- // close options menu
- await testUtils.dom.click(dropdownMenu.$('span.fa-caret-down'));
- assert.containsN(dropdownMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 4);
-
- dropdownMenu.destroy();
- });
-
- QUnit.test('close menu closes also submenus', async function (assert) {
- assert.expect(2);
-
- this.items[0].hasOptions = true;
- this.items[0].options = [
- {optionId: 1, description: "First Option"},
- {optionId: 2, description: "Second Option"}
- ];
- this.items[0].currentOptionIds = new Set();
- var dropdownMenu = await createDropdownMenu(this.items);
- // open dropdown menu
- testUtils.dom.click(dropdownMenu.$('button:first'));
- // open options menu
- await testUtils.dom.click(dropdownMenu.$('span.fa-caret-right'));
- assert.containsN(dropdownMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 7);
- await testUtils.dom.click(dropdownMenu.$('button:first'));
- await testUtils.dom.click(dropdownMenu.$('button:first'));
- assert.containsN(dropdownMenu, '.dropdown-divider, .dropdown-item, .dropdown-item-text', 4);
-
- dropdownMenu.destroy();
- });
-
- QUnit.test('click on an option should trigger the event "item_option_clicked" with appropriate data', async function (assert) {
- assert.expect(18);
-
- var self = this;
- var eventNumber = 0;
- this.items[0].hasOptions = true;
- this.items[0].options = [
- {optionId: 1, description: "First Option"},
- {optionId: 2, description: "Second Option"}
- ];
- this.items[0].currentOptionIds = new Set();
- var dropdownMenu = await createDropdownMenu(this.items, {
- intercepts: {
- item_option_clicked: function (ev) {
- eventNumber++;
- assert.strictEqual(ev.data.id, 1);
- if (eventNumber === 1) {
- assert.strictEqual(ev.data.optionId, 1);
- self.items[0].isActive = true;
- self.items[0].currentOptionIds.add(1);
- }
- if (eventNumber === 2) {
- assert.strictEqual(ev.data.optionId, 2);
- self.items[0].currentOptionIds = new Set([1,2]);
- }
- if (eventNumber === 3) {
- assert.strictEqual(ev.data.optionId, 1);
- self.items[0].currentOptionIds = new Set([2]);
- }
- if (eventNumber === 4) {
- assert.strictEqual(ev.data.optionId, 2);
- self.items[0].isActive = false;
- self.items[0].currentOptionIds.clear();
- }
- dropdownMenu.update(self.items);
- },
- },
- });
- await testUtils.nextTick();
- // open dropdown menu
- await testUtils.dom.click(dropdownMenu.$('button:first'));
- assert.containsN(dropdownMenu, '.dropdown-divider, .o_menu_item', 4);
- await testUtils.dom.clickFirst(dropdownMenu.$('.o_menu_item'));
- // click on first option
- await testUtils.dom.click(dropdownMenu.$('.o_item_option > .dropdown-item').eq(0));
- assert.hasClass(dropdownMenu.$('.o_menu_item > .dropdown-item').first(), 'selected');
- assert.hasClass(dropdownMenu.$('.o_item_option> .dropdown-item').eq(0),'selected');
- assert.doesNotHaveClass(dropdownMenu.$('.o_item_option > .dropdown-item').eq(1), 'selected');
- // click on second option
- await testUtils.dom.click($('.o_item_option > .dropdown-item').eq(1));
- assert.hasClass(dropdownMenu.$('.o_menu_item > .dropdown-item').first(), 'selected');
- assert.hasClass(dropdownMenu.$('.o_item_option > .dropdown-item').eq(0), 'selected');
- assert.hasClass(dropdownMenu.$('.o_item_option > .dropdown-item').eq(1), 'selected');
- // click again on first option
- await testUtils.dom.click(dropdownMenu.$('.o_item_option > .dropdown-item').eq(0));
- // click again on second option
- await testUtils.dom.click($('.o_item_option > .dropdown-item').eq(1));
- assert.doesNotHaveClass(dropdownMenu.$('.o_menu_item > .dropdown-item').first(), 'selected');
- assert.doesNotHaveClass(dropdownMenu.$('.o_item_option > .dropdown-item').eq(0), 'selected');
- assert.doesNotHaveClass(dropdownMenu.$('.o_item_option > .dropdown-item').eq(1), 'selected');
-
- dropdownMenu.destroy();
- });
-});
-});