odoo.define('web.owl_dialog_tests', function (require) { "use strict"; const LegacyDialog = require('web.Dialog'); const makeTestEnvironment = require('web.test_env'); const Dialog = require('web.OwlDialog'); const testUtils = require('web.test_utils'); const { Component, tags, useState } = owl; const EscapeKey = { key: 'Escape', keyCode: 27, which: 27 }; const { xml } = tags; QUnit.module('core', {}, function () { QUnit.module('OwlDialog'); QUnit.test("Rendering of all props", async function (assert) { assert.expect(35); class SubComponent extends Component { // Handlers _onClick() { assert.step('subcomponent_clicked'); } } SubComponent.template = xml`
`; class Parent extends Component { constructor() { super(...arguments); this.state = useState({ textContent: "sup" }); } // Handlers _onButtonClicked(ev) { assert.step('button_clicked'); } _onDialogClosed() { assert.step('dialog_closed'); } } Parent.components = { Dialog, SubComponent }; Parent.env = makeTestEnvironment(); Parent.template = xml` `; const parent = new Parent(); await parent.mount(testUtils.prepareTarget()); const dialog = document.querySelector('.o_dialog'); // Helper function async function changeProps(key, value) { parent.state[key] = value; await testUtils.nextTick(); } // Basic layout with default properties assert.containsOnce(dialog, '.modal.o_technical_modal'); assert.hasClass(dialog.querySelector('.modal .modal-dialog'), 'modal-lg'); assert.containsOnce(dialog, '.modal-header > button.close'); assert.containsOnce(dialog, '.modal-footer > button.btn.btn-primary'); assert.strictEqual(dialog.querySelector('.modal-body').innerText.trim(), "sup", "Subcomponent should match with its given text"); // Backdrop (default: 'static') // Static backdrop click should focus first button // => we need to reset that property dialog.querySelector('.btn-primary').blur(); // Remove the focus explicitely assert.containsNone(document.body, '.modal-backdrop'); // No backdrop *element* for Odoo modal... assert.notEqual(window.getComputedStyle(dialog.querySelector('.modal')).backgroundColor, 'rgba(0, 0, 0, 0)'); // ... but a non transparent modal await testUtils.dom.click(dialog.querySelector('.modal')); assert.strictEqual(document.activeElement, dialog.querySelector('.btn-primary'), "Button should be focused when clicking on backdrop"); assert.verifySteps([]); // Ensure not closed dialog.querySelector('.btn-primary').blur(); // Remove the focus explicitely await changeProps('backdrop', false); assert.containsNone(document.body, '.modal-backdrop'); // No backdrop *element* for Odoo modal... assert.strictEqual(window.getComputedStyle(dialog.querySelector('.modal')).backgroundColor, 'rgba(0, 0, 0, 0)'); await testUtils.dom.click(dialog.querySelector('.modal')); assert.notEqual(document.activeElement, dialog.querySelector('.btn-primary'), "Button should not be focused when clicking on backdrop 'false'"); assert.verifySteps([]); // Ensure not closed await changeProps('backdrop', true); assert.containsNone(document.body, '.modal-backdrop'); // No backdrop *element* for Odoo modal... assert.notEqual(window.getComputedStyle(dialog.querySelector('.modal')).backgroundColor, 'rgba(0, 0, 0, 0)'); // ... but a non transparent modal await testUtils.dom.click(dialog.querySelector('.modal')); assert.notEqual(document.activeElement, dialog.querySelector('.btn-primary'), "Button should not be focused when clicking on backdrop 'true'"); assert.verifySteps(['dialog_closed']); // Dialog class (default: '') await changeProps('contentClass', 'my_dialog_class'); assert.hasClass(dialog.querySelector('.modal-content'), 'my_dialog_class'); // Full screen (default: false) assert.doesNotHaveClass(dialog.querySelector('.modal'), 'o_modal_full'); await changeProps('fullscreen', true); assert.hasClass(dialog.querySelector('.modal'), 'o_modal_full'); // Size class (default: 'large') await changeProps('size', 'extra-large'); assert.strictEqual(dialog.querySelector('.modal-dialog').className, 'modal-dialog modal-xl', "Modal should have taken the class modal-xl"); await changeProps('size', 'medium'); assert.strictEqual(dialog.querySelector('.modal-dialog').className, 'modal-dialog', "Modal should not have any additionnal class with 'medium'"); await changeProps('size', 'small'); assert.strictEqual(dialog.querySelector('.modal-dialog').className, 'modal-dialog modal-sm', "Modal should have taken the class modal-sm"); // Subtitle (default: '') await changeProps('subtitle', "The Subtitle"); assert.strictEqual(dialog.querySelector('span.o_subtitle').innerText.trim(), "The Subtitle", "Subtitle should match with its given text"); // Technical (default: true) assert.hasClass(dialog.querySelector('.modal'), 'o_technical_modal'); await changeProps('technical', false); assert.doesNotHaveClass(dialog.querySelector('.modal'), 'o_technical_modal'); // Title (default: 'Odoo') assert.strictEqual(dialog.querySelector('h4.modal-title').innerText.trim(), "Odoo" + "The Subtitle", "Title should match with its default text"); await changeProps('title', "The Title"); assert.strictEqual(dialog.querySelector('h4.modal-title').innerText.trim(), "The Title" + "The Subtitle", "Title should match with its given text"); // Reactivity of buttons await testUtils.dom.click(dialog.querySelector('.modal-footer .btn-primary')); // Render footer (default: true) await changeProps('renderFooter', false); assert.containsNone(dialog, '.modal-footer'); // Render header (default: true) await changeProps('renderHeader', false); assert.containsNone(dialog, '.header'); // Reactivity of subcomponents await changeProps('textContent', "wassup"); assert.strictEqual(dialog.querySelector('.o_subcomponent').innerText.trim(), "wassup", "Subcomponent should match with its given text"); await testUtils.dom.click(dialog.querySelector('.o_subcomponent')); assert.verifySteps(['button_clicked', 'subcomponent_clicked']); parent.destroy(); }); QUnit.test("Interactions between multiple dialogs", async function (assert) { assert.expect(22); class Parent extends Component { constructor() { super(...arguments); this.dialogIds = useState([]); } // Handlers _onDialogClosed(id) { assert.step(`dialog_${id}_closed`); this.dialogIds.splice(this.dialogIds.findIndex(d => d === id), 1); } } Parent.components = { Dialog }; Parent.env = makeTestEnvironment(); Parent.template = xml`