Skip to content
Permalink
Browse files

[FIX] web: focus on close button when before closing a modal

During the clickEverywhere test, when a modal is opened, the hide method
is called to bypass it. This is not realistic and does not work in some
cases.

For example in Point of sale, menu "Reporting/Sales Details", a modal is
opened with a DateTimePicker (tempus dominus) already opened.
When hiding or closing the modal, the DateTimePicker needs to perform
some cleanup. If the modal is simply hidden, the DateTimePicker is not
cleanly destroyed.

With this commit, a modal is closed by clicking on its close button and
before that, the focus is set on the close button to let the
datepicker widget do its stuff on losing focus.

Also, a more realistic click is done by trigerring more events (code
adapted from tour helper).

closes #32038

Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
  • Loading branch information...
d-fence committed Mar 21, 2019
1 parent 3a56e34 commit 39e71353c5d58f7af6b3270911a24d98b73cad4e
Showing with 30 additions and 8 deletions.
  1. +30 −8 addons/web/static/src/js/tools/test_menus.js
@@ -100,7 +100,7 @@
}).then(function(){
// no effect in community
var $homeMenu = $("nav.o_main_navbar > a.o_menu_toggle.fa-th");
$homeMenu.click();
_click($homeMenu);
return new Promise(function(resolve){
setTimeout(function(){
resolve();
@@ -123,13 +123,16 @@
console.log("Testing menu", element.innerText.trim(), " ", element.dataset.menuXmlid);
testedMenus.push(element.dataset.menuXmlid);
var startActionCount = clientActionCount;
element.click();
_click($(element));
var isModal = false;
return waitForCondition(function() {
// sometimes, the app is just a modal that needs to be closed
var $modal = $('.modal[role="dialog"][open="open"]');
if ($modal.length > 0) {
$modal.modal('hide');
var $closeButton = $('header > button.close');
if ($closeButton.length > 0) {
_click($closeButton);
} else { $modal.modal('hide'); }
isModal = true;
return true;
}
@@ -178,7 +181,7 @@
setTimeout(function() {
var $element = $("nav.o_cp_switch_buttons > button[data-view-type=" + viewType + "]");
console.log('Clicking on: ', $element[0].dataset.viewType, ' view switcher');
$element.click();
_click($element);
},250);
var waitViewSwitch = waitForCondition(function(){
return $('.o_action_manager> .o_action.o_view_controller').data('view-type') === viewType;
@@ -198,7 +201,7 @@
var $filters = $('.o_filters_menu > .o_menu_item');
console.log("Testing " + $filters.length + " filters");
var filter_ids = _.compact(_.map($filters, function(f) { return f.dataset.id}));
_.each(filter_ids, function(filter_id){
filter_ids.forEach(function(filter_id){
filterProm = filterProm.then(function(){
var currentViewCount = viewUpdateCount;
var $filter = $('.o_menu_item[data-id="' + filter_id + '"] a');
@@ -208,16 +211,16 @@
return Promise.resolve();
}
console.log('Clicking on filter "', $filter.text().trim(), '"');
$filter[0].click();
_click($filter);
setTimeout(function() {
var $filterOption = $('.o_menu_item .o_item_option[data-item_id="' + filter_id + '"]:not(.selected) a');
// In case the filter is a date filter, we need to click on the first filter option (like 'today','This week' ...)
if ($filterOption.length > 0) {
console.log('Clicking on filter option "', $filterOption[0], '"');
$filterOption[0].click();
_click($filterOption);
console.log('And now on filter again');
$filter = $('.o_menu_item[data-id="' + filter_id + '"] a');
$filter[0].click(); // To avoid that the next view fold the options
_click($filter); // To avoid that the next view fold the options
}
}, 250);
return waitForCondition(function() {
@@ -277,5 +280,24 @@
}


/*
* More realistic click action.
* @param {jQueryElement} $element the element on which to perform the click
*/
function _click($element) {
triggerMouseEvent($element, "mouseover");
triggerMouseEvent($element, "mouseenter");
triggerMouseEvent($element, "mousedown");
triggerMouseEvent($element, "mouseup");
triggerMouseEvent($element, "focus");
triggerMouseEvent($element, "click");

function triggerMouseEvent($el, type, count) {
var e = document.createEvent("MouseEvents");
e.initMouseEvent(type, true, true, window, count || 0, 0, 0, 0, 0, false, false, false, false, 0, $el[0]);
$el[0].dispatchEvent(e);
}
}

exports.clickEverywhere = clickEverywhere;
})(window);

0 comments on commit 39e7135

Please sign in to comment.
You can’t perform that action at this time.