diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/web/static/tests/helpers/test_utils.js | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/web/static/tests/helpers/test_utils.js')
| -rw-r--r-- | addons/web/static/tests/helpers/test_utils.js | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/addons/web/static/tests/helpers/test_utils.js b/addons/web/static/tests/helpers/test_utils.js new file mode 100644 index 00000000..33aa4327 --- /dev/null +++ b/addons/web/static/tests/helpers/test_utils.js @@ -0,0 +1,282 @@ +odoo.define('web.test_utils', async function (require) { + "use strict"; + + /** + * Test Utils + * + * In this module, we define various utility functions to help simulate a mock + * environment as close as possible as a real environment. The main function is + * certainly createView, which takes a bunch of parameters and give you back an + * instance of a view, appended in the dom, ready to be tested. + */ + + const ajax = require('web.ajax'); + const core = require('web.core'); + const relationalFields = require('web.relational_fields'); + const session = require('web.session'); + const testUtilsCreate = require('web.test_utils_create'); + const testUtilsControlPanel = require('web.test_utils_control_panel'); + const testUtilsDom = require('web.test_utils_dom'); + const testUtilsFields = require('web.test_utils_fields'); + const testUtilsFile = require('web.test_utils_file'); + const testUtilsForm = require('web.test_utils_form'); + const testUtilsGraph = require('web.test_utils_graph'); + const testUtilsKanban = require('web.test_utils_kanban'); + const testUtilsMock = require('web.test_utils_mock'); + const testUtilsModal = require('web.test_utils_modal'); + const testUtilsPivot = require('web.test_utils_pivot'); + const tools = require('web.tools'); + + + function deprecated(fn, type) { + const msg = `Helper 'testUtils.${fn.name}' is deprecated. ` + + `Please use 'testUtils.${type}.${fn.name}' instead.`; + return tools.deprecated(fn, msg); + } + + /** + * Helper function, make a promise with a public resolve function. Note that + * this is not standard and should not be used outside of tests... + * + * @returns {Promise + resolve and reject function} + */ + function makeTestPromise() { + let resolve; + let reject; + const promise = new Promise(function (_resolve, _reject) { + resolve = _resolve; + reject = _reject; + }); + promise.resolve = function () { + resolve.apply(null, arguments); + return promise; + }; + promise.reject = function () { + reject.apply(null, arguments); + return promise; + }; + return promise; + } + + /** + * Make a promise with public resolve and reject functions (see + * @makeTestPromise). Perform an assert.step when the promise is + * resolved/rejected. + * + * @param {Object} assert instance object with the assertion methods + * @param {function} assert.step + * @param {string} str message to pass to assert.step + * @returns {Promise + resolve and reject function} + */ + function makeTestPromiseWithAssert(assert, str) { + const prom = makeTestPromise(); + prom.then(() => assert.step('ok ' + str)).catch(function () { }); + prom.catch(() => assert.step('ko ' + str)); + return prom; + } + + /** + * Create a new promise that can be waited by the caller in order to execute + * code after the next microtask tick and before the next jobqueue tick. + * + * @return {Promise} an already fulfilled promise + */ + async function nextMicrotaskTick() { + return Promise.resolve(); + } + + /** + * Returns a promise that will be resolved after the tick after the + * nextAnimationFrame + * + * This is usefull to guarantee that OWL has had the time to render + * + * @returns {Promise} + */ + async function nextTick() { + return testUtilsDom.returnAfterNextAnimationFrame(); + } + + /** + * Calls nextTick. While we have a hybrid implemetation (Owl + legacy), we may + * have situations where waiting for a single nextTick isn't enough. For instance, + * having a layer of Owl components, above a layer of legacy widgets, above a + * layer of Owl components requires two nextTick for the whole hierarchy to be + * rendered into the DOM. In those situation, one should use this helper, which + * will be removed (alongside all its calls) in the future. + * + * @returns {Promise} + */ + async function owlCompatibilityNextTick() { + return nextTick(); + } + + // Loading static files cannot be properly simulated when their real content is + // really needed. This is the case for static XML files so we load them here, + // before starting the qunit test suite. + // (session.js is in charge of loading the static xml bundle and we also have + // to load xml files that are normally lazy loaded by specific widgets). + await Promise.all([ + session.is_bound, + ajax.loadXML('/web/static/src/xml/crash_manager.xml', core.qweb), + ajax.loadXML('/web/static/src/xml/debug.xml', core.qweb), + ajax.loadXML('/web/static/src/xml/dialog.xml', core.qweb), + ajax.loadXML('/web/static/src/xml/translation_dialog.xml', core.qweb), + ]); + setTimeout(function () { + // 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 + relationalFields.FieldMany2One.prototype.AUTOCOMPLETE_DELAY = 0; + + // this is done with the hope that tests are + // only started all together... + QUnit.start(); + }, 0); + return { + mock: { + addMockEnvironment: testUtilsMock.addMockEnvironment, + addMockEnvironmentOwl: testUtilsMock.addMockEnvironmentOwl, + intercept: testUtilsMock.intercept, + patch: testUtilsMock.patch, + patchDate: testUtilsMock.patchDate, + unpatch: testUtilsMock.unpatch, + fieldsViewGet: testUtilsMock.fieldsViewGet, + patchSetTimeout: testUtilsMock.patchSetTimeout, + }, + controlPanel: { + // Generic interactions + toggleMenu: testUtilsControlPanel.toggleMenu, + toggleMenuItem: testUtilsControlPanel.toggleMenuItem, + toggleMenuItemOption: testUtilsControlPanel.toggleMenuItemOption, + isItemSelected: testUtilsControlPanel.isItemSelected, + isOptionSelected: testUtilsControlPanel.isOptionSelected, + getMenuItemTexts: testUtilsControlPanel.getMenuItemTexts, + // Button interactions + getButtons: testUtilsControlPanel.getButtons, + // FilterMenu interactions + toggleFilterMenu: testUtilsControlPanel.toggleFilterMenu, + toggleAddCustomFilter: testUtilsControlPanel.toggleAddCustomFilter, + applyFilter: testUtilsControlPanel.applyFilter, + // GroupByMenu interactions + toggleGroupByMenu: testUtilsControlPanel.toggleGroupByMenu, + toggleAddCustomGroup: testUtilsControlPanel.toggleAddCustomGroup, + selectGroup: testUtilsControlPanel.selectGroup, + applyGroup: testUtilsControlPanel.applyGroup, + // FavoriteMenu interactions + toggleFavoriteMenu: testUtilsControlPanel.toggleFavoriteMenu, + toggleSaveFavorite: testUtilsControlPanel.toggleSaveFavorite, + editFavoriteName: testUtilsControlPanel.editFavoriteName, + saveFavorite: testUtilsControlPanel.saveFavorite, + deleteFavorite: testUtilsControlPanel.deleteFavorite, + // ComparisonMenu interactions + toggleComparisonMenu: testUtilsControlPanel.toggleComparisonMenu, + // SearchBar interactions + getFacetTexts: testUtilsControlPanel.getFacetTexts, + removeFacet: testUtilsControlPanel.removeFacet, + editSearch: testUtilsControlPanel.editSearch, + validateSearch: testUtilsControlPanel.validateSearch, + // Action menus interactions + toggleActionMenu: testUtilsControlPanel.toggleActionMenu, + // Pager interactions + pagerPrevious: testUtilsControlPanel.pagerPrevious, + pagerNext: testUtilsControlPanel.pagerNext, + getPagerValue: testUtilsControlPanel.getPagerValue, + getPagerSize: testUtilsControlPanel.getPagerSize, + setPagerValue: testUtilsControlPanel.setPagerValue, + // View switcher + switchView: testUtilsControlPanel.switchView, + }, + dom: { + triggerKeypressEvent: testUtilsDom.triggerKeypressEvent, + triggerMouseEvent: testUtilsDom.triggerMouseEvent, + triggerPositionalMouseEvent: testUtilsDom.triggerPositionalMouseEvent, + dragAndDrop: testUtilsDom.dragAndDrop, + find: testUtilsDom.findItem, + getNode: testUtilsDom.getNode, + openDatepicker: testUtilsDom.openDatepicker, + click: testUtilsDom.click, + clickFirst: testUtilsDom.clickFirst, + clickLast: testUtilsDom.clickLast, + triggerEvents: testUtilsDom.triggerEvents, + triggerEvent: testUtilsDom.triggerEvent, + }, + form: { + clickEdit: testUtilsForm.clickEdit, + clickSave: testUtilsForm.clickSave, + clickCreate: testUtilsForm.clickCreate, + clickDiscard: testUtilsForm.clickDiscard, + reload: testUtilsForm.reload, + }, + graph: { + reload: testUtilsGraph.reload, + }, + kanban: { + reload: testUtilsKanban.reload, + clickCreate: testUtilsKanban.clickCreate, + quickCreate: testUtilsKanban.quickCreate, + toggleGroupSettings: testUtilsKanban.toggleGroupSettings, + toggleRecordDropdown: testUtilsKanban.toggleRecordDropdown, + }, + modal: { + clickButton: testUtilsModal.clickButton, + }, + pivot: { + clickMeasure: testUtilsPivot.clickMeasure, + toggleMeasuresDropdown: testUtilsPivot.toggleMeasuresDropdown, + reload: testUtilsPivot.reload, + }, + fields: { + many2one: { + createAndEdit: testUtilsFields.clickM2OCreateAndEdit, + clickOpenDropdown: testUtilsFields.clickOpenM2ODropdown, + clickHighlightedItem: testUtilsFields.clickM2OHighlightedItem, + clickItem: testUtilsFields.clickM2OItem, + searchAndClickItem: testUtilsFields.searchAndClickM2OItem, + }, + editInput: testUtilsFields.editInput, + editSelect: testUtilsFields.editSelect, + editAndTrigger: testUtilsFields.editAndTrigger, + triggerKey: testUtilsFields.triggerKey, + triggerKeydown: testUtilsFields.triggerKeydown, + triggerKeyup: testUtilsFields.triggerKeyup, + }, + file: { + createFile: testUtilsFile.createFile, + dragoverFile: testUtilsFile.dragoverFile, + dropFile: testUtilsFile.dropFile, + dropFiles: testUtilsFile.dropFiles, + inputFiles: testUtilsFile.inputFiles, + }, + + createActionManager: testUtilsCreate.createActionManager, + createComponent: testUtilsCreate.createComponent, + createControlPanel: testUtilsCreate.createControlPanel, + createDebugManager: testUtilsCreate.createDebugManager, + createAsyncView: testUtilsCreate.createView, + createCalendarView: testUtilsCreate.createCalendarView, + createView: testUtilsCreate.createView, + createModel: testUtilsCreate.createModel, + createParent: testUtilsCreate.createParent, + makeTestPromise: makeTestPromise, + makeTestPromiseWithAssert: makeTestPromiseWithAssert, + nextMicrotaskTick: nextMicrotaskTick, + nextTick: nextTick, + owlCompatibilityNextTick: owlCompatibilityNextTick, + prepareTarget: testUtilsCreate.prepareTarget, + returnAfterNextAnimationFrame: testUtilsDom.returnAfterNextAnimationFrame, + + // backward-compatibility + addMockEnvironment: deprecated(testUtilsMock.addMockEnvironment, 'mock'), + dragAndDrop: deprecated(testUtilsDom.dragAndDrop, 'dom'), + fieldsViewGet: deprecated(testUtilsMock.fieldsViewGet, 'mock'), + intercept: deprecated(testUtilsMock.intercept, 'mock'), + openDatepicker: deprecated(testUtilsDom.openDatepicker, 'dom'), + patch: deprecated(testUtilsMock.patch, 'mock'), + patchDate: deprecated(testUtilsMock.patchDate, 'mock'), + triggerKeypressEvent: deprecated(testUtilsDom.triggerKeypressEvent, 'dom'), + triggerMouseEvent: deprecated(testUtilsDom.triggerMouseEvent, 'dom'), + triggerPositionalMouseEvent: deprecated(testUtilsDom.triggerPositionalMouseEvent, 'dom'), + unpatch: deprecated(testUtilsMock.unpatch, 'mock'), + }; +}); |
