This rev. is a partial backport of abf32b8b, so that the newly
introduced helpers are already available in 12.0.
closes odoo/odoo#28827
173 lines
5.2 KiB
JavaScript
173 lines
5.2 KiB
JavaScript
odoo.define('web.test_utils_fields', function (require) {
|
|
"use strict";
|
|
|
|
/**
|
|
* Field Test Utils
|
|
*
|
|
* This module defines various utility functions to help testing field widgets.
|
|
*
|
|
* Note that all methods defined in this module are exported in the main
|
|
* testUtils file.
|
|
*/
|
|
|
|
var concurrency = require('web.concurrency');
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Public functions
|
|
//------------------------------------------------------------------------------
|
|
|
|
/**
|
|
* Sets the value of an element and then, trigger all specified events.
|
|
* Note that this helper also checks the unicity of the target.
|
|
*
|
|
* Example:
|
|
* testUtils.fields.editAndTrigger($('selector'), 'test', ['input', 'change']);
|
|
*
|
|
* @param {jQuery} $el should target an input, textarea or select
|
|
* @param {string|number} value
|
|
* @param {string[]} events
|
|
*/
|
|
function editAndTrigger($el, value, events) {
|
|
if ($el.length !== 1) {
|
|
throw new Error(`target ${$el.selector} has length ${$el.length} instead of 1`);
|
|
}
|
|
$el.val(value);
|
|
events.forEach(function (event) {
|
|
$el.trigger(event);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Sets the value of an input.
|
|
*
|
|
* Note that this helper also checks the unicity of the target.
|
|
*
|
|
* Example:
|
|
* testUtils.fields.editInput($('selector'), 'somevalue');
|
|
*
|
|
* @param {jQuery} $el
|
|
* @param {string|number} value
|
|
*/
|
|
function editInput($el, value) {
|
|
editAndTrigger($el, value, ['input']);
|
|
}
|
|
|
|
/**
|
|
* Sets the value of a select.
|
|
*
|
|
* Note that this helper also checks the unicity of the target.
|
|
*
|
|
* Example:
|
|
* testUtils.fields.editSelect($('selector'), 'somevalue');
|
|
*
|
|
* @param {jQuery} $el
|
|
* @param {string|number} value
|
|
*/
|
|
function editSelect($el, value) {
|
|
editAndTrigger($el, value, ['change']);
|
|
}
|
|
|
|
/**
|
|
* Click to open the dropdown on a many2one
|
|
*
|
|
* @param {string} fieldName
|
|
* @param {[string]} selector if set, this will restrict the search for the m2o
|
|
* input
|
|
* @returns {HTMLInputElement} the main many2one input
|
|
*/
|
|
function clickOpenM2ODropdown(fieldName, selector) {
|
|
var m2oSelector = `${selector || ''} .o_field_many2one[name=${fieldName}] input`;
|
|
var matches = document.querySelectorAll(m2oSelector);
|
|
if (matches.length !== 1) {
|
|
throw new Error(`cannot open m2o: selector ${selector} has been found ${matches.length} instead of 1`);
|
|
}
|
|
matches[0].click();
|
|
return matches[0];
|
|
}
|
|
|
|
/**
|
|
* Click on the active (highlighted) selection in a m2o dropdown.
|
|
*
|
|
* @param {string} fieldName
|
|
* @param {[string]} selector if set, this will restrict the search for the m2o
|
|
* input
|
|
*/
|
|
function clickM2OHighlightedItem(fieldName, selector) {
|
|
var m2oSelector = `${selector || ''} .o_field_many2one[name=${fieldName}] input`;
|
|
var $dropdown = $(m2oSelector).autocomplete('widget');
|
|
// clicking on an li (no matter which one), will select the focussed one
|
|
$dropdown.find('li:first()').click();
|
|
}
|
|
|
|
/**
|
|
* Click on a menuitem in the m2o dropdown. This helper will target an element
|
|
* which contains some specific text. Note that it assumes that the dropdown
|
|
* is currently open.
|
|
*
|
|
* Example:
|
|
* testUtils.fields.many2one.clickM2OItem('partner_id', 'George');
|
|
*
|
|
* @param {string} fieldName
|
|
* @param {string} searchText
|
|
*/
|
|
function clickM2OItem(fieldName, searchText) {
|
|
var m2oSelector = `.o_field_many2one[name=${fieldName}] input`;
|
|
var $dropdown = $(m2oSelector).autocomplete('widget');
|
|
var $target = $dropdown.find(`li:contains(${searchText})`).first();
|
|
if ($target.length !== 1 || !$target.is(':visible')) {
|
|
throw new Error('Menu item should be unique and visible');
|
|
}
|
|
$target.mouseenter().click();
|
|
}
|
|
|
|
/**
|
|
* This helper is useful to test many2one fields. Here is what it does:
|
|
* - click to open the dropdown
|
|
* - enter a search string in the input
|
|
* - wait for the selection
|
|
* - click on the active menuitem
|
|
*
|
|
* Example:
|
|
* testUtils.fields.many2one.searchAndClickM2OItem('partner_id', 'George');
|
|
*
|
|
* @param {string} fieldName
|
|
* @param {[Object]} options
|
|
* @param {[string]} options.selector
|
|
* @param {[string]} options.search
|
|
* @returns {Promise}
|
|
*/
|
|
function searchAndClickM2OItem(fieldName, options) {
|
|
options = options || {};
|
|
|
|
var input = clickOpenM2ODropdown(fieldName, options.selector);
|
|
|
|
var def;
|
|
if (options.search) {
|
|
// jquery autocomplete refines the search in a setTimeout() parameterized
|
|
// with a delay, so we force this delay to 0 s.t. the dropdown is filtered
|
|
// directly on the next tick
|
|
var $input = $(input);
|
|
var delay = $input.autocomplete('option', 'delay');
|
|
$input.autocomplete('option', 'delay', 0);
|
|
input.value = options.search;
|
|
input.dispatchEvent(new Event('input'));
|
|
$input.autocomplete('option', 'delay', delay);
|
|
def = concurrency.delay(0);
|
|
}
|
|
|
|
return $.when(def).then(function () {
|
|
clickM2OHighlightedItem(fieldName, options.selector);
|
|
});
|
|
}
|
|
return {
|
|
clickOpenM2ODropdown: clickOpenM2ODropdown,
|
|
clickM2OHighlightedItem: clickM2OHighlightedItem,
|
|
clickM2OItem: clickM2OItem,
|
|
editAndTrigger: editAndTrigger,
|
|
editInput: editInput,
|
|
editSelect: editSelect,
|
|
searchAndClickM2OItem: searchAndClickM2OItem,
|
|
};
|
|
|
|
});
|