From c02e4316bb4d05adc4ce8645ad28cdc0b809f99d Mon Sep 17 00:00:00 2001 From: "Michael (mcm)" Date: Tue, 13 Sep 2022 13:41:52 +0000 Subject: [PATCH 1/4] [IMP] web: open m2o record in target current This commit adds an option to many2one field to open the record either in target new (dialog) or target current (replace view) which is now the default. task id: 2822553 X-original-commit: abe26f6eebb450512b35c25094329f85b98c15d9 Part-of: odoo/odoo#101118 --- .../views/fields/many2one/many2one_field.js | 9 ++- .../views/fields/many2one/many2one_field.xml | 3 +- .../views/fields/many2one_field_tests.js | 63 +++++++++++++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/views/fields/many2one/many2one_field.js b/addons/web/static/src/views/fields/many2one/many2one_field.js index eec6ccd950b..4a7a6e97d10 100644 --- a/addons/web/static/src/views/fields/many2one/many2one_field.js +++ b/addons/web/static/src/views/fields/many2one/many2one_field.js @@ -188,7 +188,11 @@ export class Many2OneField extends Component { } } onExternalBtnClick() { - this.openDialog(this.resId); + if (this.props.openTarget === "current") { + this.openAction(); + } else { + this.openDialog(this.resId); + } } async onBarcodeBtnClick() { const barcode = await BarcodeScanner.scanBarcode(); @@ -259,6 +263,7 @@ Many2OneField.props = { relation: { type: String, optional: true }, string: { type: String, optional: true }, canScanBarcode: { type: Boolean, optional: true }, + openTarget: { type: String, validate: (v) => ["current", "new"].includes(v), optional: true }, }; Many2OneField.defaultProps = { canOpen: true, @@ -270,6 +275,7 @@ Many2OneField.defaultProps = { searchLimit: 7, string: "", canScanBarcode: false, + openTarget: "current", }; Many2OneField.displayName = _lt("Many2one"); @@ -295,6 +301,7 @@ Many2OneField.extractProps = ({ attrs, field }) => { string: attrs.string || field.string, createNameField: attrs.options.create_name_field, canScanBarcode: canScanBarcode, + openTarget: attrs.open_target, }; }; diff --git a/addons/web/static/src/views/fields/many2one/many2one_field.xml b/addons/web/static/src/views/fields/many2one/many2one_field.xml index bb596bf9e01..beb27606cdb 100644 --- a/addons/web/static/src/views/fields/many2one/many2one_field.xml +++ b/addons/web/static/src/views/fields/many2one/many2one_field.xml @@ -45,7 +45,8 @@ - + @@ -68,11 +53,8 @@ Discard -
- -
diff --git a/addons/web/static/src/views/form/form_error_dialog/form_error_dialog.js b/addons/web/static/src/views/form/form_error_dialog/form_error_dialog.js new file mode 100644 index 00000000000..c93447a2b30 --- /dev/null +++ b/addons/web/static/src/views/form/form_error_dialog/form_error_dialog.js @@ -0,0 +1,66 @@ +/** @odoo-module **/ + +import { Dialog } from "@web/core/dialog/dialog"; +import { RPCError } from "@web/core/network/rpc_service"; +import { registry } from "@web/core/registry"; + +const { Component, onWillDestroy } = owl; + +export class FormErrorDialog extends Component { + setup() { + const { data, message } = this.props; + if (data && data.arguments && data.arguments.length > 0) { + this.message = data.arguments[0]; + } else { + this.message = message; + } + } + + async discard() { + await this.props.onDiscard(); + this.props.close(); + } +} +FormErrorDialog.template = "web.FormErrorDialog"; +FormErrorDialog.components = { Dialog }; + +function makeFormErrorHandler(onDiscard) { + return (env, error, originalError) => { + if ( + originalError && + originalError.legacy && + originalError.message && + originalError.message instanceof RPCError + ) { + const event = originalError.event; + originalError = originalError.message; + error.unhandledRejectionEvent.preventDefault(); + if (event.isDefaultPrevented()) { + // in theory, here, event was already handled + return true; + } + event.preventDefault(); + + env.services.dialog.add(FormErrorDialog, { + message: originalError.message, + data: originalError.data, + onDiscard, + }); + + return true; + } + return false; + }; +} + +let formId = 0; + +export function useFormErrorDialog(onDiscard) { + const errorHandlerKey = `form_error_handler_${++formId}`; + registry + .category("error_handlers") + .add(errorHandlerKey, makeFormErrorHandler(onDiscard), { sequence: 0 }); + onWillDestroy(() => { + registry.category("error_handlers").remove(errorHandlerKey); + }); +} diff --git a/addons/web/static/src/views/form/form_error_dialog/form_error_dialog.scss b/addons/web/static/src/views/form/form_error_dialog/form_error_dialog.scss new file mode 100644 index 00000000000..dac7ad8b96d --- /dev/null +++ b/addons/web/static/src/views/form/form_error_dialog/form_error_dialog.scss @@ -0,0 +1,10 @@ +.o_form_error_dialog { + border: none; + padding: 2rem; + top: 50%; + transform: translateY(-50%); + + footer { + border: none; + } +} diff --git a/addons/web/static/src/views/form/form_error_dialog/form_error_dialog.xml b/addons/web/static/src/views/form/form_error_dialog/form_error_dialog.xml new file mode 100644 index 00000000000..d3cbbc549a5 --- /dev/null +++ b/addons/web/static/src/views/form/form_error_dialog/form_error_dialog.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/addons/web/static/src/views/form/form_label.js b/addons/web/static/src/views/form/form_label.js index 3c50689dabf..c4f386b2727 100644 --- a/addons/web/static/src/views/form/form_label.js +++ b/addons/web/static/src/views/form/form_label.js @@ -8,7 +8,7 @@ const { Component, xml } = owl; export class FormLabel extends Component { get className() { - const { invalid, empty } = fieldVisualFeedback( + const { invalid, empty, readonly } = fieldVisualFeedback( this.props.fieldInfo.FieldComponent, this.props.record, this.props.fieldName, @@ -21,6 +21,9 @@ export class FormLabel extends Component { if (empty) { classes.push("o_form_label_empty"); } + if (readonly) { + classes.push("o_form_label_readonly"); + } return classes.join(" "); } diff --git a/addons/web/static/src/views/form/form_renderer.js b/addons/web/static/src/views/form/form_renderer.js index 8725b330733..eccf98f060f 100644 --- a/addons/web/static/src/views/form/form_renderer.js +++ b/addons/web/static/src/views/form/form_renderer.js @@ -43,21 +43,21 @@ export class FormRenderer extends Component { if (!disableAutofocus) { const rootRef = useRef("compiled_view_root"); useEffect( - (isInEdition, rootEl) => { + (isVirtual, rootEl) => { if (!rootEl) { return; } let elementToFocus; - if (isInEdition) { + if (isVirtual) { elementToFocus = (autofocusFieldId && rootEl.querySelector(`#${autofocusFieldId}`)) || - rootEl.querySelector(`.o_content .o_field_widget input`); + rootEl.querySelector(`.o_content .o_field_widget input[type="text"]`); } if (elementToFocus) { elementToFocus.focus(); } }, - () => [this.props.record.isInEdition, rootRef.el] + () => [this.props.record.isVirtual, rootRef.el] ); } } diff --git a/addons/web/static/src/views/form/form_status_indicator/form_status_indicator.js b/addons/web/static/src/views/form/form_status_indicator/form_status_indicator.js new file mode 100644 index 00000000000..a3263ccc40e --- /dev/null +++ b/addons/web/static/src/views/form/form_status_indicator/form_status_indicator.js @@ -0,0 +1,35 @@ +/** @odoo-module **/ + +const { Component } = owl; + +export class FormStatusIndicator extends Component { + get displayButtons() { + return this.indicatorMode !== "saved"; + } + + get indicatorMode() { + if (this.props.model.root.isVirtual) { + return this.props.model.root.isValid ? "dirty" : "invalid"; + } else if (!this.props.model.root.isValid) { + return "invalid"; + } else if (this.props.model.root.isDirty) { + return "dirty"; + } else { + return "saved"; + } + } + + async discard() { + await this.props.discard(); + } + async save() { + await this.props.save(); + } +} +FormStatusIndicator.template = "web.FormStatusIndicator"; +FormStatusIndicator.props = { + model: Object, + save: Function, + discard: Function, + isDisabled: Boolean, +}; diff --git a/addons/web/static/src/views/form/form_status_indicator/form_status_indicator.scss b/addons/web/static/src/views/form/form_status_indicator/form_status_indicator.scss new file mode 100644 index 00000000000..c1ccb2e97ae --- /dev/null +++ b/addons/web/static/src/views/form/form_status_indicator/form_status_indicator.scss @@ -0,0 +1,15 @@ +.o_form_status_indicator:not(.o_form_status_indicator_new_record) { + .o_form_status_indicator_buttons { + visibility: hidden; + } + + &:hover { + span { + visibility: hidden; + } + + .o_form_status_indicator_buttons:not(.o_form_status_indicator_buttons_hidden) { + visibility: visible; + } + } +} diff --git a/addons/web/static/src/views/form/form_status_indicator/form_status_indicator.xml b/addons/web/static/src/views/form/form_status_indicator/form_status_indicator.xml new file mode 100644 index 00000000000..ecfa52083b7 --- /dev/null +++ b/addons/web/static/src/views/form/form_status_indicator/form_status_indicator.xml @@ -0,0 +1,21 @@ + + + + +
+ + + Unable to save + + + Unsaved changes + + +
+ + +
+
+
+ +
diff --git a/addons/web/static/src/views/form/form_view.js b/addons/web/static/src/views/form/form_view.js index 8d24b6b19df..271add520b6 100644 --- a/addons/web/static/src/views/form/form_view.js +++ b/addons/web/static/src/views/form/form_view.js @@ -6,13 +6,14 @@ import { RelationalModel } from "../basic_relational_model"; import { FormArchParser } from "./form_arch_parser"; import { FormController } from "./form_controller"; import { FormCompiler } from "./form_compiler"; +import { FormControlPanel } from "./control_panel/form_control_panel"; export const formView = { type: "form", display_name: "Form", multiRecord: false, - display: { controlPanel: { ["top-right"]: false } }, searchMenuTypes: [], + ControlPanel: FormControlPanel, Controller: FormController, Renderer: FormRenderer, ArchParser: FormArchParser, diff --git a/addons/web/static/src/views/form/status_bar_buttons/status_bar_buttons.js b/addons/web/static/src/views/form/status_bar_buttons/status_bar_buttons.js index d525216b306..7ac55d22731 100644 --- a/addons/web/static/src/views/form/status_bar_buttons/status_bar_buttons.js +++ b/addons/web/static/src/views/form/status_bar_buttons/status_bar_buttons.js @@ -11,10 +11,7 @@ export class StatusBarButtons extends Component { return []; } return Object.entries(this.props.slots) - .filter( - (entry) => - entry[1].isVisible && (entry[1].displayInReadOnly ? this.props.readonly : true) - ) + .filter((entry) => entry[1].isVisible) .map((entry) => entry[0]); } } diff --git a/addons/web/static/src/views/list/list_renderer.js b/addons/web/static/src/views/list/list_renderer.js index 8233fc80f6a..113c995dfff 100644 --- a/addons/web/static/src/views/list/list_renderer.js +++ b/addons/web/static/src/views/list/list_renderer.js @@ -572,13 +572,6 @@ export class ListRenderer extends Component { if (column.type === "button_group") { classNames.push("o_list_button"); } - // note: remove this oe_read/edit_only logic when form view - // will always be in edit mode - if (/\boe_edit_only\b/.test(column.className)) { - classNames.push("oe_edit_only"); - } else if (/\boe_read_only\b/.test(column.className)) { - classNames.push("oe_read_only"); - } if (column.widget) { classNames.push(`o_${column.widget}_cell`); } diff --git a/addons/web/static/src/views/view_button/view_button.js b/addons/web/static/src/views/view_button/view_button.js index afbd9b4cee6..e9c7222a764 100644 --- a/addons/web/static/src/views/view_button/view_button.js +++ b/addons/web/static/src/views/view_button/view_button.js @@ -92,6 +92,8 @@ export class ViewButton extends Component { this.env[DROPDOWN].close(); } }, + disableAction: this.props.disable, + enableAction: this.props.enable, }); } @@ -133,7 +135,9 @@ ViewButton.props = [ "hotkey?", "icon?", "defaultRank?", + "disable?", "disabled?", + "enable?", "size?", "tabindex?", "title?", @@ -145,4 +149,6 @@ ViewButton.defaultProps = { tag: "button", className: "", clickParams: {}, + disable: () => {}, + enable: () => {}, }; diff --git a/addons/web/static/src/views/view_button/view_button_hook.js b/addons/web/static/src/views/view_button/view_button_hook.js index c237325e7c7..955b34e5ec3 100644 --- a/addons/web/static/src/views/view_button/view_button_hook.js +++ b/addons/web/static/src/views/view_button/view_button_hook.js @@ -15,12 +15,15 @@ function disableButtons(el) { return btns; } -function enableButtons(el, manuallyDisabledButtons) { +function enableButtons(el, manuallyDisabledButtons, enableAction) { if (el) { for (const btn of manuallyDisabledButtons) { btn.removeAttribute("disabled"); } } + if (enableAction) { + enableAction(); + } } function undefinedAsTrue(val) { @@ -37,8 +40,17 @@ export function useViewButtons(model, ref, options = {}) { return true; }); useSubEnv({ - async onClickViewButton({ clickParams, getResParams, beforeExecute }) { + async onClickViewButton({ + clickParams, + getResParams, + beforeExecute, + disableAction, + enableAction, + }) { const manuallyDisabledButtons = disableButtons(getEl()); + if (disableAction) { + disableAction(); + } async function execute() { let _continue = true; @@ -48,7 +60,7 @@ export function useViewButtons(model, ref, options = {}) { _continue = _continue && undefinedAsTrue(await beforeExecuteAction(clickParams)); if (!_continue) { - enableButtons(getEl(), manuallyDisabledButtons); + enableButtons(getEl(), manuallyDisabledButtons, enableAction); return; } const params = getResParams(); @@ -85,7 +97,7 @@ export function useViewButtons(model, ref, options = {}) { error = _e; await doActionParams.onClose(); } - enableButtons(getEl(), manuallyDisabledButtons); + enableButtons(getEl(), manuallyDisabledButtons, enableAction); if (error) { return Promise.reject(error); } @@ -100,7 +112,7 @@ export function useViewButtons(model, ref, options = {}) { }; dialog.add(ConfirmationDialog, dialogProps, { onClose: resolve }); }); - enableButtons(getEl(), manuallyDisabledButtons); + enableButtons(getEl(), manuallyDisabledButtons, enableAction); } else { return execute(); } diff --git a/addons/web/static/src/webclient/settings_form_view/settings_form_view.js b/addons/web/static/src/webclient/settings_form_view/settings_form_view.js index 46bad63fee1..795138af49a 100644 --- a/addons/web/static/src/webclient/settings_form_view/settings_form_view.js +++ b/addons/web/static/src/webclient/settings_form_view/settings_form_view.js @@ -1,6 +1,7 @@ /** @odoo-module **/ import { registry } from "@web/core/registry"; +import { ControlPanel } from "@web/search/control_panel/control_panel"; import { formView } from "@web/views/form/form_view"; import { SettingsFormController } from "./settings_form_controller"; import { SettingsFormRenderer } from "./settings_form_renderer"; @@ -10,6 +11,7 @@ export const settingsFormView = { ...formView, display: {}, buttonTemplate: "web.SettingsFormView.Buttons", + ControlPanel: ControlPanel, Controller: SettingsFormController, Compiler: SettingsFormCompiler, Renderer: SettingsFormRenderer, diff --git a/addons/web/static/tests/helpers/utils.js b/addons/web/static/tests/helpers/utils.js index 5d32f1e4450..e48dc2f256e 100644 --- a/addons/web/static/tests/helpers/utils.js +++ b/addons/web/static/tests/helpers/utils.js @@ -385,16 +385,17 @@ export function clickCreate(htmlElement) { } export function clickEdit(htmlElement) { - if (htmlElement.querySelectorAll(".o_form_button_edit").length) { - return click(htmlElement, ".o_form_button_edit"); - } else if (htmlElement.querySelectorAll(".o_list_button_edit").length) { + if (htmlElement.querySelectorAll(".o_list_button_edit").length) { return click(htmlElement, ".o_list_button_edit"); } else { throw new Error("No edit button found to be clicked."); } } -export function clickSave(htmlElement) { +export async function clickSave(htmlElement) { + if (htmlElement.querySelectorAll(".o_form_status_indicator").length) { + await mouseEnter(htmlElement, ".o_form_status_indicator"); + } if (htmlElement.querySelectorAll(".o_form_button_save").length) { return click(htmlElement, ".o_form_button_save"); } else if (htmlElement.querySelectorAll(".o_list_button_save").length) { @@ -404,7 +405,10 @@ export function clickSave(htmlElement) { } } -export function clickDiscard(htmlElement) { +export async function clickDiscard(htmlElement) { + if (htmlElement.querySelectorAll(".o_form_status_indicator").length) { + await mouseEnter(htmlElement, ".o_form_status_indicator"); + } if (htmlElement.querySelectorAll(".o_form_button_cancel").length) { return click(htmlElement, ".o_form_button_cancel"); } else if (htmlElement.querySelectorAll(".o_list_button_discard").length) { diff --git a/addons/web/static/tests/mobile/mobile_form_view_tests.js b/addons/web/static/tests/mobile/mobile_form_view_tests.js index c21fcac3bd5..bb29f0f4452 100644 --- a/addons/web/static/tests/mobile/mobile_form_view_tests.js +++ b/addons/web/static/tests/mobile/mobile_form_view_tests.js @@ -3,7 +3,6 @@ import { registry } from "@web/core/registry"; import { click, - clickEdit, clickSave, editInput, getFixture, @@ -124,7 +123,6 @@ QUnit.module("Mobile Views", ({ beforeEach }) => { ); // change display_name to update buttons modifiers and make it visible - await clickEdit(fixture); await editInput(fixture, ".o_field_widget[name=display_name] input", "test"); await clickSave(fixture); assert.containsOnce( @@ -135,43 +133,6 @@ QUnit.module("Mobile Views", ({ beforeEach }) => { } ); - QUnit.test( - `statusbar "Action" button not displayed in edit mode with .oe_read_only button`, - async (assert) => { - await makeView({ - type: "form", - resModel: "partner", - serverData, - arch: ` -
-
-
- - - - - -
- `, - }); - - assert.containsNone( - fixture, - ".o_statusbar_buttons .dropdown", - "dropdown should not be there" - ); - - await clickSave(fixture); - assert.containsOnce( - fixture, - ".o_statusbar_buttons .dropdown", - "dropdown should not be there" - ); - } - ); - QUnit.test( `statusbar "Action" button shouldn't be displayed for only one visible button`, async (assert) => { @@ -195,8 +156,6 @@ QUnit.module("Mobile Views", ({ beforeEach }) => { `, }); - await clickEdit(fixture); - // There should be a simple statusbar button and no action dropdown assert.containsNone( fixture, @@ -248,7 +207,6 @@ QUnit.module("Mobile Views", ({ beforeEach }) => { `, }); - await clickEdit(fixture); // Now there should an action dropdown, because there are two visible buttons assert.containsOnce( fixture, @@ -449,8 +407,6 @@ QUnit.module("Mobile Views", ({ beforeEach }) => { }, }); - await clickEdit(fixture); - window.scrollTo({ top: 265, left: 0 }); assert.strictEqual(window.scrollY, 265, "Should have scrolled 265 px vertically"); assert.strictEqual(window.screenLeft, 0, "Should be 0 px from left as it is"); diff --git a/addons/web/static/tests/mobile/mobile_statusbar_field_tests.js b/addons/web/static/tests/mobile/mobile_statusbar_field_tests.js index 03254bb08e9..91f50eaa4c6 100644 --- a/addons/web/static/tests/mobile/mobile_statusbar_field_tests.js +++ b/addons/web/static/tests/mobile/mobile_statusbar_field_tests.js @@ -102,10 +102,10 @@ QUnit.module("Mobile Fields", ({ beforeEach }) => { `, }); - assert.hasClass( + assert.doesNotHaveClass( fixture.querySelector(".o_field_statusbar"), "o_field_empty", - "statusbar widget should have class o_field_empty" + "statusbar widget should have class o_field_empty in edit" ); assert.containsOnce( fixture, diff --git a/addons/web/static/tests/views/fields/ace_editor_field_tests.js b/addons/web/static/tests/views/fields/ace_editor_field_tests.js index 7e45300da30..d028d922f38 100644 --- a/addons/web/static/tests/views/fields/ace_editor_field_tests.js +++ b/addons/web/static/tests/views/fields/ace_editor_field_tests.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { clickEdit, getFixture, triggerEvents } from "@web/../tests/helpers/utils"; +import { getFixture, triggerEvents } from "@web/../tests/helpers/utils"; import { pagerNext } from "@web/../tests/search/helpers"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; @@ -70,7 +70,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await clickEdit(target); await triggerEvents(target, ".ace-view-editor textarea", ["focus", "click"]); assert.hasClass(target.querySelector(".ace-view-editor"), "ace_focus"); }); diff --git a/addons/web/static/tests/views/fields/binary_field_tests.js b/addons/web/static/tests/views/fields/binary_field_tests.js index e680e657b46..edd77e93518 100644 --- a/addons/web/static/tests/views/fields/binary_field_tests.js +++ b/addons/web/static/tests/views/fields/binary_field_tests.js @@ -4,6 +4,7 @@ import { registerCleanup } from "@web/../tests/helpers/cleanup"; import { makeMockXHR } from "@web/../tests/helpers/mock_services"; import { click, + clickSave, editInput, getFixture, makeDeferred, @@ -66,8 +67,81 @@ QUnit.module("Fields", (hooks) => { QUnit.module("BinaryField"); + QUnit.test("BinaryField is correctly rendered (readonly)", async function (assert) { + assert.expect(6); + + async function send(data) { + assert.ok(data instanceof FormData); + assert.strictEqual( + data.get("field"), + "document", + "we should download the field document" + ); + assert.strictEqual( + data.get("data"), + "coucou==\n", + "we should download the correct data" + ); + + this.status = 200; + this.response = new Blob([data.get("data")], { type: "text/plain" }); + } + const MockXHR = makeMockXHR("", send); + + patchWithCleanup( + browser, + { + XMLHttpRequest: MockXHR, + }, + { pure: true } + ); + + await makeView({ + serverData, + type: "form", + resModel: "partner", + arch: ` +
+ + + `, + resId: 1, + }); + assert.containsOnce( + target, + '.o_field_widget[name="document"] a > .fa-download', + "the binary field should be rendered as a downloadable link in readonly" + ); + assert.strictEqual( + target.querySelector('.o_field_widget[name="document"]').textContent, + "coucou.txt", + "the binary field should display the name of the file in the link" + ); + assert.strictEqual( + target.querySelector(".o_field_char").textContent, + "coucou.txt", + "the filename field should have the file name as value" + ); + + // Testing the download button in the field + // We must avoid the browser to download the file effectively + const prom = makeDeferred(); + const downloadOnClick = (ev) => { + const target = ev.target; + if (target.tagName === "A" && "download" in target.attributes) { + ev.preventDefault(); + document.removeEventListener("click", downloadOnClick); + prom.resolve(); + } + }; + document.addEventListener("click", downloadOnClick); + registerCleanup(() => document.removeEventListener("click", downloadOnClick)); + await click(target.querySelector('.o_field_widget[name="document"] a')); + await prom; + }); + QUnit.test("BinaryField is correctly rendered", async function (assert) { - assert.expect(15); + assert.expect(9); async function send(data) { assert.ok(data instanceof FormData); @@ -106,39 +180,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - assert.containsOnce( - target, - '.o_field_widget[name="document"] a > .fa-download', - "the binary field should be rendered as a downloadable link in readonly" - ); - assert.strictEqual( - target.querySelector('.o_field_widget[name="document"]').textContent, - "coucou.txt", - "the binary field should display the name of the file in the link" - ); - assert.strictEqual( - target.querySelector(".o_field_char").textContent, - "coucou.txt", - "the filename field should have the file name as value" - ); - - // Testing the download button in the field - // We must avoid the browser to download the file effectively - const prom = makeDeferred(); - const downloadOnClick = (ev) => { - const target = ev.target; - if (target.tagName === "A" && "download" in target.attributes) { - ev.preventDefault(); - document.removeEventListener("click", downloadOnClick); - prom.resolve(); - } - }; - document.addEventListener("click", downloadOnClick); - registerCleanup(() => document.removeEventListener("click", downloadOnClick)); - await click(target.querySelector('.o_field_widget[name="document"] a')); - await prom; - - await click(target, ".o_form_button_edit"); assert.containsNone( target, @@ -178,7 +219,7 @@ QUnit.module("Fields", (hooks) => { "the filename field should be empty since we removed the file" ); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.containsNone( target, '.o_field_widget[name="document"] a > .fa-download', @@ -230,8 +271,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await click(target, ".o_form_button_edit"); - const file = new File(["test"], "fake_file.txt", { type: "text/plain" }); await editInput(target, ".o_field_binary .o_input_file", file); diff --git a/addons/web/static/tests/views/fields/boolean_favorite_field_tests.js b/addons/web/static/tests/views/fields/boolean_favorite_field_tests.js index 9a780983108..6881f4254f8 100644 --- a/addons/web/static/tests/views/fields/boolean_favorite_field_tests.js +++ b/addons/web/static/tests/views/fields/boolean_favorite_field_tests.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { click, getFixture } from "@web/../tests/helpers/utils"; +import { click, clickSave, getFixture } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; let serverData; @@ -114,8 +114,6 @@ QUnit.module("Fields", (hooks) => { 'the label should say "Add to Favorites"' ); - // switch to edit mode - await click(target, ".o_form_button_edit"); assert.containsOnce( target, ".o_field_widget .o_favorite > a i.fa.fa-star-o", @@ -141,7 +139,7 @@ QUnit.module("Fields", (hooks) => { ); // save - await click(target, ".o_form_button_save"); + await clickSave(target); assert.containsOnce( target, ".o_field_widget .o_favorite > a i.fa.fa-star", @@ -188,7 +186,7 @@ QUnit.module("Fields", (hooks) => { ); // save - await click(target, ".o_list_button_save"); + await clickSave(target); assert.containsOnce( target, ".o_data_row:first .o_field_widget .o_favorite > a i.fa.fa-star-o", diff --git a/addons/web/static/tests/views/fields/boolean_field_tests.js b/addons/web/static/tests/views/fields/boolean_field_tests.js index 86c698d885d..5278b69d38c 100644 --- a/addons/web/static/tests/views/fields/boolean_field_tests.js +++ b/addons/web/static/tests/views/fields/boolean_field_tests.js @@ -2,6 +2,7 @@ import { click, + clickSave, getFixture, nextTick, triggerEvent, @@ -50,15 +51,6 @@ QUnit.module("Fields", (hooks) => { `, }); - assert.containsOnce(target, ".o_field_boolean input:checked", "checkbox should be checked"); - assert.containsOnce( - target, - ".o_field_boolean input:disabled", - "checkbox should be disabled" - ); - - // switch to edit mode and check the result - await click(target, ".o_form_button_edit"); assert.containsOnce( target, ".o_field_boolean input:checked", @@ -79,15 +71,13 @@ QUnit.module("Fields", (hooks) => { ); // save - await click(target, ".o_form_button_save"); + await clickSave(target); assert.containsNone( target, ".o_field_boolean input:checked", "checkbox should still no longer be checked" ); - // switch to edit mode and test the opposite change - await click(target, ".o_form_button_edit"); assert.containsNone( target, ".o_field_boolean input:checked", @@ -155,7 +145,7 @@ QUnit.module("Fields", (hooks) => { ); // save - await click(target, ".o_form_button_save"); + await clickSave(target); assert.containsOnce( target, ".o_field_boolean input:checked", @@ -211,7 +201,7 @@ QUnit.module("Fields", (hooks) => { await click(cell, ".o-checkbox"); // save - await click(target.querySelector(".o_list_button_save")); + await clickSave(target); cell = target.querySelector("tr.o_data_row td:not(.o_list_record_selector)"); assert.ok( cell.querySelector(".o-checkbox input:not(:checked)").disabled, @@ -236,7 +226,7 @@ QUnit.module("Fields", (hooks) => { await click(cell, ".o-checkbox"); // Save - await click(target.querySelector(".o_list_button_save")); + await clickSave(target); assert.containsN( target, "tbody td:not(.o_list_record_selector) .o-checkbox", @@ -282,14 +272,7 @@ QUnit.module("Fields", (hooks) => { serverData, arch: `
`, }); - assert.containsOnce(target, ".o_field_boolean input:checked", "checkbox should be checked"); - assert.containsOnce( - target, - ".o_field_boolean input:disabled", - "checkbox should be disabled" - ); - await click(target, ".o_form_button_edit"); assert.containsOnce( target, ".o_field_boolean input:checked", diff --git a/addons/web/static/tests/views/fields/boolean_toggle_field_tests.js b/addons/web/static/tests/views/fields/boolean_toggle_field_tests.js index 1f28dab830b..558154e33b4 100644 --- a/addons/web/static/tests/views/fields/boolean_toggle_field_tests.js +++ b/addons/web/static/tests/views/fields/boolean_toggle_field_tests.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { click, clickEdit, getFixture } from "@web/../tests/helpers/utils"; +import { click, getFixture } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; let serverData; @@ -79,7 +79,7 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - assert.containsOnce(target, ".o_form_readonly"); + assert.containsOnce(target, ".o_form_editable"); assert.containsOnce(target, ".form-check.o_boolean_toggle"); assert.notOk(target.querySelector(".o_boolean_toggle input").disabled); assert.notOk(target.querySelector(".o_boolean_toggle input").checked); @@ -98,8 +98,6 @@ QUnit.module("Fields", (hooks) => { assert.containsOnce(target, ".form-check.o_boolean_toggle"); assert.ok(target.querySelector(".o_boolean_toggle input").disabled); - await click(target.querySelector(".o_form_button_edit")); - assert.ok(target.querySelector(".o_boolean_toggle input").disabled); }); QUnit.test("BooleanToggleField is enabled in edit mode", async function (assert) { @@ -112,7 +110,6 @@ QUnit.module("Fields", (hooks) => { }); assert.containsOnce(target, ".form-check.o_boolean_toggle"); - await click(target.querySelector(".o_form_button_edit")); assert.notOk(target.querySelector(".o_boolean_toggle input").disabled); assert.notOk(target.querySelector(".o_boolean_toggle input").checked); @@ -165,8 +162,6 @@ QUnit.module("Fields", (hooks) => { ".form-check.o_boolean_toggle", "Boolean toggle widget applied to boolean field" ); - - await clickEdit(target); assert.containsNone(target, ".o_boolean_toggle input:checked"); await click(target, ".o_boolean_toggle"); @@ -193,8 +188,6 @@ QUnit.module("Fields", (hooks) => { ".form-check.o_boolean_toggle", "Boolean toggle widget applied to boolean field" ); - - await clickEdit(target); assert.containsNone(target, ".o_boolean_toggle input:checked"); await click(target, ".o_boolean_toggle"); diff --git a/addons/web/static/tests/views/fields/char_field_tests.js b/addons/web/static/tests/views/fields/char_field_tests.js index 05bd6634daf..95748c10fdf 100644 --- a/addons/web/static/tests/views/fields/char_field_tests.js +++ b/addons/web/static/tests/views/fields/char_field_tests.js @@ -3,6 +3,7 @@ import { registry } from "@web/core/registry"; import { click, + clickSave, editInput, getFixture, makeDeferred, @@ -147,14 +148,6 @@ QUnit.module("Fields", (hooks) => { `, }); - assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "yop", - "the value should be displayed properly" - ); - - // switch to edit mode and check the result - await click(target, ".o_form_button_edit"); assert.containsOnce( target, ".o_field_widget input[type='text']", @@ -170,9 +163,9 @@ QUnit.module("Fields", (hooks) => { await editInput(target, ".o_field_widget input[type='text']", "limbo"); // save - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input[type='text']").value, "limbo", "the new value should be displayed" ); @@ -203,12 +196,8 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); - await editInput(target, ".o_field_widget input[type='text']", ""); - - // save - await click(target, ".o_form_button_save"); + await clickSave(target); } ); @@ -229,9 +218,6 @@ QUnit.module("Fields", (hooks) => { `, }); - - await click(target, ".o_form_button_edit"); - assert.hasAttrValue( target.querySelector("input"), "maxlength", @@ -271,7 +257,7 @@ QUnit.module("Fields", (hooks) => { await editInput(cell, "input", "brolo"); // save - await click(target, ".o_list_button_save"); + await clickSave(target); cell = target.querySelector("tbody td:not(.o_list_record_selector)"); assert.doesNotHaveClass( cell.parentElement, @@ -336,8 +322,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); - assert.hasClass(target.querySelector("[name=foo] input"), "o_field_translate"); assert.containsOnce( @@ -465,7 +449,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await click(target, ".o_form_button_edit"); // this will not affect the translate_fields effect until the record is // saved but is set for consistency of the test @@ -546,12 +529,10 @@ QUnit.module("Fields", (hooks) => { `, }); - await click(target, ".o_form_button_edit"); await editInput(target, "[name='foo'] input", ""); - - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "", "the value should have been properly escaped" ); @@ -576,16 +557,9 @@ QUnit.module("Fields", (hooks) => { `, }); - await click(target, ".o_form_button_edit"); - await editInput(target, ".o_field_widget[name='foo'] input", " abc "); - await editInput(target, ".o_field_widget[name='foo2'] input", " def "); - - await click(target, ".o_form_button_save"); - - // edit mode - await click(target, ".o_form_button_edit"); + await clickSave(target); assert.strictEqual( target.querySelector(".o_field_widget[name='foo'] input").value, "abc", @@ -629,7 +603,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); await click(target, ".o_field_x2many_list_row_add a"); assert.strictEqual( target.querySelector(".o_field_widget[name='foo'] input").value, @@ -763,8 +736,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); - assert.strictEqual( target.querySelector(".o_field_widget[name='foo'] input").value, "yop", @@ -802,7 +773,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await click(target.querySelector(".o_form_button_edit")); assert.hasAttrValue( target.querySelector('.o_field_widget[name="display_name"] input'), "autocomplete", @@ -820,7 +790,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await click(target.querySelector(".o_form_button_edit")); assert.hasAttrValue( target.querySelector('.o_field_widget[name="display_name"] input'), "autocomplete", @@ -838,12 +807,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - assert.strictEqual( - target.querySelector('.o_field_widget[name="foo"]').innerText, - "***", - "password should be displayed with stars" - ); - await click(target.querySelector(".o_form_button_edit")); assert.strictEqual( target.querySelector('.o_field_widget[name="foo"] input').value, "yop", @@ -856,6 +819,30 @@ QUnit.module("Fields", (hooks) => { ); }); + QUnit.test("input field: readonly password", async function (assert) { + await makeView({ + type: "form", + resModel: "partner", + resId: 1, + serverData, + arch: ` +
+ + `, + }); + + assert.notEqual( + target.querySelector(".o_field_char").textContent, + "yop", + "password field value should not be visible in read mode" + ); + assert.strictEqual( + target.querySelector(".o_field_char").textContent, + "***", + "password field value should be hidden with '*' in read mode" + ); + }); + QUnit.test("input field: change password value", async function (assert) { await makeView({ type: "form", @@ -868,19 +855,6 @@ QUnit.module("Fields", (hooks) => { `, }); - assert.notEqual( - target.querySelector(".o_field_char").textContent, - "yop", - "password field value should not be visible in read mode" - ); - assert.strictEqual( - target.querySelector(".o_field_char").textContent, - "***", - "password field value should be hidden with '*' in read mode" - ); - - await click(target, ".o_form_button_edit"); - assert.hasAttrValue( target.querySelector(".o_field_char input"), "type", @@ -908,14 +882,6 @@ QUnit.module("Fields", (hooks) => { `, }); - assert.strictEqual( - target.querySelector(".o_field_char").textContent, - "", - "password field value should be empty in read mode" - ); - - await click(target, ".o_form_button_edit"); - assert.hasAttrValue( target.querySelector(".o_field_char input"), "type", diff --git a/addons/web/static/tests/views/fields/color_field_tests.js b/addons/web/static/tests/views/fields/color_field_tests.js index abf8a7beafa..abab67061d0 100644 --- a/addons/web/static/tests/views/fields/color_field_tests.js +++ b/addons/web/static/tests/views/fields/color_field_tests.js @@ -1,5 +1,5 @@ /** @odoo-module **/ -import { click, editInput, getFixture, clickEdit } from "@web/../tests/helpers/utils"; +import { click, editInput, getFixture } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; let serverData; @@ -129,7 +129,6 @@ QUnit.module("Fields", (hooks) => { "field has the default color set as background if no value has been selected" ); assert.strictEqual(target.querySelector(".o_field_color input").value, "#000000"); - await clickEdit(target); await editInput(target, ".o_field_char[name='foo'] input", "someValue"); assert.verifySteps([ 'onchange [[1],{"id":1,"foo":"someValue","hex_color":false},"foo",{"foo":"1","hex_color":""}]', diff --git a/addons/web/static/tests/views/fields/color_picker_field_tests.js b/addons/web/static/tests/views/fields/color_picker_field_tests.js index b8d5d78d2a3..f5050684848 100644 --- a/addons/web/static/tests/views/fields/color_picker_field_tests.js +++ b/addons/web/static/tests/views/fields/color_picker_field_tests.js @@ -59,9 +59,6 @@ QUnit.module("Fields", (hooks) => { `, }); - // switch to edit mode - await click(target, ".o_form_button_edit"); - assert.hasClass( target.querySelectorAll(".o_field_color_picker button"), "o_colorlist_item_color_0", @@ -102,9 +99,6 @@ QUnit.module("Fields", (hooks) => { `, }); - // switch to edit mode - await click(target, ".o_form_button_edit"); - await click(target, ".o_field_color_picker button"); assert.strictEqual( diff --git a/addons/web/static/tests/views/fields/date_field_tests.js b/addons/web/static/tests/views/fields/date_field_tests.js index 5a17d19374f..a26b6cc2179 100644 --- a/addons/web/static/tests/views/fields/date_field_tests.js +++ b/addons/web/static/tests/views/fields/date_field_tests.js @@ -9,6 +9,8 @@ import { patchTimeZone, triggerEvent, triggerEvents, + clickSave, + clickCreate, } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; import { makeFakeLocalizationService } from "@web/../tests/helpers/mock_services"; @@ -120,7 +122,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await click(target, ".o_form_button_edit"); assert.containsNone( document.body, ".bootstrap-datetimepicker-widget", @@ -155,11 +156,11 @@ QUnit.module("Fields", (hooks) => { assert.containsOnce( target, - ".o_field_widget > span", - "should have one span in the form view" + ".o_field_widget input", + "should have one input in the form view" ); assert.strictEqual( - target.querySelector(".o_field_widget > span").textContent, + target.querySelector(".o_field_widget input").value, "", "and it should be empty" ); @@ -175,7 +176,6 @@ QUnit.module("Fields", (hooks) => { serverData, arch: '
', }); - await click(target, ".o_form_button_edit"); const input = target.querySelector(".o_field_widget[name='date'] input"); assert.strictEqual(input.value, "02/03/2017"); @@ -196,7 +196,6 @@ QUnit.module("Fields", (hooks) => { serverData, arch: '
', }); - await click(target, ".o_form_button_edit"); const input = target.querySelector(".o_field_widget[name='date'] input"); assert.strictEqual(input.value, ""); @@ -215,7 +214,6 @@ QUnit.module("Fields", (hooks) => { serverData, arch: '
', }); - await click(target, ".o_form_button_edit"); await click(target, ".o_datepicker input"); // open datepicker and select a date @@ -236,7 +234,7 @@ QUnit.module("Fields", (hooks) => { }); QUnit.test("DateField in form view (with positive time zone offset)", async function (assert) { - assert.expect(8); + assert.expect(7); patchTimeZone(120); // Should be ignored by date fields @@ -257,14 +255,6 @@ QUnit.module("Fields", (hooks) => { }, }); - assert.strictEqual( - target.querySelector(".o_field_date").textContent, - "02/03/2017", - "the date should be correctly displayed in readonly" - ); - - // switch to edit mode - await click(target, ".o_form_button_edit"); assert.strictEqual( target.querySelector(".o_datepicker_input").value, "02/03/2017", @@ -304,9 +294,9 @@ QUnit.module("Fields", (hooks) => { ); // save - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_date").textContent, + target.querySelector(".o_field_date input").value, "02/22/2017", "the selected date should be displayed after saving" ); @@ -323,14 +313,6 @@ QUnit.module("Fields", (hooks) => { arch: '
', }); - assert.strictEqual( - target.querySelector(".o_field_date").textContent, - "02/03/2017", - "the date should be correctly displayed in readonly" - ); - - // switch to edit mode - await click(target, ".o_form_button_edit"); assert.strictEqual( target.querySelector(".o_datepicker_input").value, "02/03/2017", @@ -351,7 +333,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await click(target, ".o_form_button_edit"); await click(target, ".o_datepicker input"); assert.containsOnce( @@ -379,8 +360,6 @@ QUnit.module("Fields", (hooks) => { `, }); - // switch to edit mode - await click(target, ".o_form_button_edit"); // open datepicker and select another value await click(target, ".o_datepicker input"); @@ -430,8 +409,6 @@ QUnit.module("Fields", (hooks) => { `, }); - // switch to edit mode - await click(target, ".o_form_button_edit"); assert.strictEqual( target.querySelector(".o_field_widget[name='date'] input").value, @@ -439,11 +416,8 @@ QUnit.module("Fields", (hooks) => { "The existing record should have a value for the date field" ); - // save with no changes - await click(target, ".o_form_button_save"); - //Create a new record - await click(target, ".o_form_button_create"); + await clickCreate(target); assert.notOk( target.querySelector(".o_field_widget[name='date'] input").value, "The new record should not have a value that the framework would have set" @@ -513,7 +487,7 @@ QUnit.module("Fields", (hooks) => { ); // save - await click(target.querySelector(".o_list_button_save")); + await clickSave(target); assert.strictEqual( target.querySelector("tr.o_data_row td:not(.o_list_record_selector)").textContent, "02/22/2017", @@ -534,8 +508,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - // switch to edit mode - await click(target, ".o_form_button_edit"); assert.strictEqual( target.querySelector(".o_datepicker_input").value, @@ -553,7 +525,7 @@ QUnit.module("Fields", (hooks) => { ); // save - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( target.querySelector(".o_field_date").textContent, "", @@ -574,7 +546,6 @@ QUnit.module("Fields", (hooks) => { assert.step(method); }, }); - await click(target, ".o_form_button_edit"); assert.strictEqual( target.querySelector(".o_datepicker_input").value, @@ -585,8 +556,8 @@ QUnit.module("Fields", (hooks) => { const input = target.querySelector(".o_field_widget[name='datetime'] input"); input.value = "02/08/2017"; await triggerEvents(input, null, ["input", "change", "focusout"]); - await click(target, ".o_form_button_save"); + assert.containsOnce(target, ".o_form_saved"); assert.verifySteps(["get_views", "read"]); // should not have save as nothing changed } ); @@ -604,7 +575,6 @@ QUnit.module("Fields", (hooks) => { serverData, arch: '
', }); - await click(target, ".o_form_button_edit"); $(target).on("show.datetimepicker", () => { assert.containsOnce( @@ -660,8 +630,7 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - const dateViewForm = target.querySelector(".o_field_date").textContent; - await click(target.querySelector(".o_form_button_edit")); + const dateViewForm = target.querySelector(".o_field_date input").value; await click(target, ".o_datepicker input"); assert.strictEqual( @@ -671,9 +640,9 @@ QUnit.module("Fields", (hooks) => { ); await click(document.body.querySelector(".day[data-day*='/22/']")); const dateEditForm = target.querySelector(".o_datepicker_input").value; - await click(target.querySelector(".o_form_button_save")); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_date").textContent, + target.querySelector(".o_field_date input").value, dateEditForm, "date field should be the same as the one selected in the view form" ); @@ -692,7 +661,6 @@ QUnit.module("Fields", (hooks) => { serverData, arch: '
', }); - await click(target, ".o_form_button_edit"); const year = new Date().getFullYear(); const input = target.querySelector(".o_field_widget[name='date'] input"); diff --git a/addons/web/static/tests/views/fields/daterange_field_tests.js b/addons/web/static/tests/views/fields/daterange_field_tests.js index 58c6bbc5028..3cdf6dc4f3d 100644 --- a/addons/web/static/tests/views/fields/daterange_field_tests.js +++ b/addons/web/static/tests/views/fields/daterange_field_tests.js @@ -2,6 +2,7 @@ import { click, + clickSave, editInput, getFixture, patchDate, @@ -69,22 +70,6 @@ QUnit.module("Fields", (hooks) => { `, }); - let fields = target.querySelectorAll(".o_field_daterange"); - // Check date display correctly in readonly - assert.strictEqual( - fields[0].textContent, - "02/08/2017 15:30:00", - "the start date should be correctly displayed in readonly" - ); - assert.strictEqual( - fields[fields.length - 1].textContent, - "03/13/2017 05:30:00", - "the end date should be correctly displayed in readonly" - ); - - // Edit - await click(target, ".o_form_button_edit"); - // Check date range picker initialization assert.containsN( document.body, @@ -103,7 +88,7 @@ QUnit.module("Fields", (hooks) => { ); // open the first one - fields = target.querySelectorAll(".o_field_daterange"); + let fields = target.querySelectorAll(".o_field_daterange"); await click(fields[0].querySelector("input")); let datepicker = document.querySelector( @@ -206,12 +191,12 @@ QUnit.module("Fields", (hooks) => { ); // Save - await click(target, ".o_form_button_save"); - fields = target.querySelectorAll(".o_field_daterange"); + await clickSave(target); + fields = target.querySelectorAll(".o_field_daterange input"); // Check date after save - assert.strictEqual(fields[0].textContent, "02/08/2017 15:30:00"); - assert.strictEqual(fields[fields.length - 1].textContent, "02/09/2017 05:30:00"); + assert.strictEqual(fields[0].value, "02/08/2017 15:30:00"); + assert.strictEqual(fields[fields.length - 1].value, "02/09/2017 05:30:00"); } ); @@ -234,23 +219,6 @@ QUnit.module("Fields", (hooks) => { }); let fields = target.querySelectorAll(".o_field_daterange"); - - // Check date display correctly in readonly - assert.strictEqual( - fields[0].textContent, - "02/03/2017", - "the start date should be correctly displayed in readonly" - ); - assert.strictEqual( - fields[fields.length - 1].textContent, - "02/08/2017", - "the end date should be correctly displayed in readonly" - ); - - // Edit - await click(target, ".o_form_button_edit"); - - fields = target.querySelectorAll(".o_field_daterange"); const datepickers = document.querySelectorAll(`.daterangepicker`); // Check date range picker initialization @@ -361,17 +329,17 @@ QUnit.module("Fields", (hooks) => { ); // Save - await click(target, ".o_form_button_save"); + await clickSave(target); fields = target.querySelectorAll(".o_field_daterange"); // Check date after save assert.strictEqual( - fields[0].textContent, + fields[0].querySelector("input").value, "02/13/2017", "the start date should be '02/13/2017' after save" ); assert.strictEqual( - fields[fields.length - 1].textContent, + fields[1].querySelector("input").value, "03/18/2017", "the end date should be '03/18/2017' after save" ); @@ -399,9 +367,7 @@ QUnit.module("Fields", (hooks) => { `, }); - await click(target, ".o_form_button_edit"); await click(target.querySelector(".o_field_daterange[name='datetime'] input")); - assert.isVisible( document.querySelector(".daterangepicker[data-name='datetime']"), "date range picker should be opened" @@ -445,18 +411,16 @@ QUnit.module("Fields", (hooks) => { // check date display correctly in readonly assert.strictEqual( - target.querySelector(".o_field_daterange").textContent, + target.querySelector(".o_field_daterange input").value, "02/08/2017 15:30:00", "the start date should be correctly displayed in readonly" ); assert.strictEqual( - target.querySelectorAll(".o_field_daterange")[1].textContent, + target.querySelectorAll(".o_field_daterange input")[1].value, "03/13/2017 05:30:00", "the end date should be correctly displayed in readonly" ); - // edit form - await click(target.querySelector(".o_form_button_edit")); // update input for Datetime await editInput( target, @@ -464,12 +428,12 @@ QUnit.module("Fields", (hooks) => { "02/08/2017 11:30:00" ); // save form - await click(target.querySelector(".o_form_button_save")); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_daterange").textContent, + target.querySelector(".o_field_daterange input").value, "02/08/2017 11:30:00", - "the start date should be correctly displayed in readonly after manual update" + "the start date should be correctly displayed after manual update" ); } ); @@ -492,7 +456,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await click(target, ".o_form_button_edit"); await editInput(target, ".o_field_daterange[name='date'] input", "blabla"); // click outside daterange field await click(target); @@ -511,7 +474,7 @@ QUnit.module("Fields", (hooks) => { // again enter wrong value and try to save should raise invalid fields value await editInput(target, ".o_field_daterange[name='date'] input", "blabla"); - await click(target.querySelector(".o_form_button_save")); + await clickSave(target); assert.strictEqual( target.querySelector(".o_notification_title").textContent, "Invalid fields: " @@ -591,12 +554,12 @@ QUnit.module("Fields", (hooks) => { }); assert.strictEqual( - target.querySelector(".o_field_daterange[name='datetime']").textContent, + target.querySelector(".o_field_daterange[name='datetime'] input").value, "02/08/2017", "the start date should only show date when option formatType is Date" ); assert.strictEqual( - target.querySelector(".o_field_daterange[name='datetime_end']").textContent, + target.querySelector(".o_field_daterange[name='datetime_end'] input").value, "03/13/2017", "the end date should only show date when option formatType is Date" ); diff --git a/addons/web/static/tests/views/fields/datetime_field_tests.js b/addons/web/static/tests/views/fields/datetime_field_tests.js index 9f33d0496cf..70eb8fd068d 100644 --- a/addons/web/static/tests/views/fields/datetime_field_tests.js +++ b/addons/web/static/tests/views/fields/datetime_field_tests.js @@ -4,6 +4,7 @@ import { registry } from "@web/core/registry"; import { makeFakeLocalizationService } from "@web/../tests/helpers/mock_services"; import { click, + clickSave, editInput, getFixture, patchTimeZone, @@ -67,13 +68,11 @@ QUnit.module("Fields", (hooks) => { const expectedDateString = "02/08/2017 12:00:00"; // 10:00:00 without timezone assert.strictEqual( - target.querySelector(".o_field_datetime").textContent, + target.querySelector(".o_field_datetime input").value, expectedDateString, "the datetime should be correctly displayed in readonly" ); - // switch to edit mode - await click(target, ".o_form_button_edit"); assert.strictEqual( target.querySelector(".o_datepicker_input").value, expectedDateString, @@ -126,9 +125,9 @@ QUnit.module("Fields", (hooks) => { ); // save - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_datetime").textContent, + target.querySelector(".o_field_datetime input").value, newExpectedDateString, "the selected date should be displayed after saving" ); @@ -155,8 +154,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); - await click(target, ".o_datepicker_input"); assert.containsOnce(document.body, ".bootstrap-datetimepicker-widget"); @@ -325,7 +322,7 @@ QUnit.module("Fields", (hooks) => { ); // save - await click(target.querySelector(".o_list_button_save")); + await clickSave(target); assert.strictEqual( target.querySelector("tr.o_data_row td:not(.o_list_record_selector)").textContent, newExpectedDateString, @@ -390,8 +387,6 @@ QUnit.module("Fields", (hooks) => { }, }); - // switch to edit mode - await click(target, ".o_form_button_edit"); assert.strictEqual( target.querySelector(".o_datepicker_input").value, "02/08/2017 12:00:00", @@ -408,7 +403,7 @@ QUnit.module("Fields", (hooks) => { ); // save - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( target.querySelector(".o_field_datetime").textContent, "", @@ -452,7 +447,7 @@ QUnit.module("Fields", (hooks) => { // switch to form view await click(target, ".o_field_widget[name='p'] .o_data_cell"); assert.strictEqual( - document.body.querySelector(".modal .o_field_date[name='datetime']").textContent, + document.body.querySelector(".modal .o_field_date[name='datetime'] input").value, "02/07/2017", "the datetime (date widget) should be correctly displayed in form view" ); @@ -495,7 +490,7 @@ QUnit.module("Fields", (hooks) => { // switch to form view await click(target, ".o_field_widget[name='p'] .o_data_cell"); assert.strictEqual( - document.body.querySelector(".modal .o_field_date[name='datetime']").textContent, + document.body.querySelector(".modal .o_field_date[name='datetime'] input").value, "02/08/2017", "the datetime (date widget) should be correctly displayed in form view" ); @@ -556,8 +551,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await click(target, ".o_form_button_edit"); - const datetime = target.querySelector(".o_field_datetime input"); // Enter a beginning of date and press enter to validate @@ -573,10 +566,10 @@ QUnit.module("Fields", (hooks) => { assert.strictEqual(datetime.value, datetimeValue); // Save and check that it's still ok - await click(target, ".o_form_button_save"); + await clickSave(target); - const { textContent } = target.querySelector(".o_field_datetime span"); - assert.strictEqual(textContent, datetimeValue); + const { value } = target.querySelector(".o_field_datetime input"); + assert.strictEqual(value, datetimeValue); }); QUnit.test( @@ -595,15 +588,13 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await click(target, ".o_form_button_edit"); - await editInput(target, ".o_field_widget input", "01/08/22"); await triggerEvent(target, ".o_field_widget input", "keydown", { key: "Enter" }); assert.strictEqual(target.querySelector(".o_field_widget input").value, "01/08/2022"); // Click outside the field to check that the field is not changed - await click(target); + await clickSave(target); assert.strictEqual(target.querySelector(".o_field_widget input").value, "01/08/2022"); } ); diff --git a/addons/web/static/tests/views/fields/domain_field_tests.js b/addons/web/static/tests/views/fields/domain_field_tests.js index a4460e31347..85d413641bc 100644 --- a/addons/web/static/tests/views/fields/domain_field_tests.js +++ b/addons/web/static/tests/views/fields/domain_field_tests.js @@ -3,6 +3,7 @@ import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; import { click, + clickSave, editInput, getFixture, makeDeferred, @@ -112,7 +113,7 @@ QUnit.module("Fields", (hooks) => { }); assert.strictEqual( - target.querySelector(".o_read_mode").textContent, + target.querySelector(".o_edit_mode").textContent, "This domain is not supported.", "The widget should not crash the view, but gracefully admit its failure." ); @@ -136,7 +137,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await click(target, ".o_form_button_edit"); // As the domain is empty, there should be a button to add the first // domain part @@ -189,7 +189,7 @@ QUnit.module("Fields", (hooks) => { // Saving the form view should show a readonly domain containing the // "color" field - await click(target, ".o_form_button_save"); + await clickSave(target); assert.ok( target.querySelector(".o_field_domain").textContent.includes("Color index"), "field selector readonly value should now contain 'Color index'" @@ -216,7 +216,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await click(target, ".o_form_button_edit"); // As the domain is equal to [["id", "=", 1]] there should be a field // selector to change this @@ -293,7 +292,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await click(target, ".o_form_button_edit"); assert.strictEqual( target.querySelector(".o_domain_show_selection_button").textContent.trim(), @@ -312,7 +310,7 @@ QUnit.module("Fields", (hooks) => { ); QUnit.test("domain field: handle false domain as []", async function (assert) { - assert.expect(4); + assert.expect(3); serverData.models.partner.records[0].foo = false; serverData.models.partner.fields.bar.type = "char"; @@ -343,8 +341,6 @@ QUnit.module("Fields", (hooks) => { ".o_field_widget[name='foo']:not(.o_field_empty)", "there should be a domain field, not considered empty" ); - - await click(target, ".o_form_button_edit"); assert.containsNone( target, ".o_field_widget[name='foo'] .text-warning", @@ -460,13 +456,10 @@ QUnit.module("Fields", (hooks) => { await doAction(webClient, 1); assert.verifySteps(["[]"]); - await click(target, ".o_form_button_edit"); - assert.strictEqual( target.querySelector(".o_domain_show_selection_button").textContent.trim(), "2 record(s)" ); - assert.verifySteps(["[]"]); await editInput(target, ".o_domain_debug_input", "[['id', '<', 40]]"); // the count should not be re-computed when editing with the textarea @@ -476,15 +469,12 @@ QUnit.module("Fields", (hooks) => { ); assert.verifySteps([]); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( target.querySelector(".o_domain_show_selection_button").textContent.trim(), "1 record(s)" ); - assert.verifySteps([ - '[["id","<",40]]', // to validate the domain, before saving - '[["id","<",40]]', // to render in readonly once it has been saved - ]); + assert.verifySteps(['[["id","<",40]]']); }); QUnit.test( @@ -531,13 +521,10 @@ QUnit.module("Fields", (hooks) => { await doAction(webClient, 1); assert.verifySteps(["[]"]); - await click(target, ".o_form_button_edit"); - assert.strictEqual( target.querySelector(".o_domain_show_selection_button").textContent.trim(), "2 record(s)" ); - assert.verifySteps(["[]"]); await editInput(target, ".o_domain_debug_input", "[['abc']]"); // the count should not be re-computed when editing with the textarea @@ -547,7 +534,7 @@ QUnit.module("Fields", (hooks) => { ); assert.verifySteps([]); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.hasClass( target.querySelector(".o_field_domain"), "o_field_invalid", @@ -603,8 +590,6 @@ QUnit.module("Fields", (hooks) => { await doAction(webClient, 1); assert.verifySteps(["[]"]); - await click(target, ".o_form_button_edit"); - assert.strictEqual( target.querySelector(".o_domain_show_selection_button").textContent.trim(), "2 record(s)" @@ -616,7 +601,6 @@ QUnit.module("Fields", (hooks) => { target.querySelector(".o_domain_show_selection_button").textContent.trim(), "2 record(s)" ); - assert.verifySteps(["[]"]); // click on the refresh button await click(target, ".o_refresh_count"); @@ -709,7 +693,6 @@ QUnit.module("Fields", (hooks) => { }); await doAction(webClient, 1); - await click(target, ".o_form_button_edit"); assert.strictEqual(target.querySelector(".o_domain_debug_input").value, rawDomain); rawDomain = ` @@ -720,7 +703,7 @@ QUnit.module("Fields", (hooks) => { await editInput(target, ".o_domain_debug_input", rawDomain); assert.strictEqual(target.querySelector(".o_domain_debug_input").value, rawDomain); - await click(target, ".o_form_button_save"); + await clickSave(target); }); QUnit.test("domain field: edit through selector (dynamic content)", async function (assert) { @@ -762,8 +745,6 @@ QUnit.module("Fields", (hooks) => { await doAction(webClient, 1); assert.verifySteps(["/web/action/load", "get_views", "read", "search_count", "fields_get"]); - await click(target, ".o_form_button_edit"); - assert.verifySteps(["search_count"]); assert.strictEqual(target.querySelector(".o_domain_debug_input").value, rawDomain); assert.containsOnce(target, ".o_datepicker", "there should be a datepicker"); @@ -775,15 +756,6 @@ QUnit.module("Fields", (hooks) => { assert.strictEqual(target.querySelector(".o_domain_debug_input").value, rawDomain); assert.verifySteps([]); - // Save - await click(target, ".o_form_button_save"); - assert.verifySteps(["search_count"]); - - // Edit again - await click(target, ".o_form_button_edit"); - assert.verifySteps(["search_count"]); - assert.strictEqual(target.querySelector(".o_domain_debug_input").value, rawDomain); - // Manually input a date rawDomain = `[("date", ">=", "2020-09-09")]`; await editInput(target, ".o_datepicker_input", "09/09/2020"); @@ -791,12 +763,8 @@ QUnit.module("Fields", (hooks) => { assert.strictEqual(target.querySelector(".o_domain_debug_input").value, rawDomain); // Save - await click(target, ".o_form_button_save"); + await clickSave(target); assert.verifySteps(["write", "read", "search_count"]); - - // Edit again - await click(target, ".o_form_button_edit"); - assert.verifySteps(["search_count"]); assert.strictEqual(target.querySelector(".o_domain_debug_input").value, rawDomain); }); diff --git a/addons/web/static/tests/views/fields/email_field_tests.js b/addons/web/static/tests/views/fields/email_field_tests.js index 13d588a5633..eaaa211bc6c 100644 --- a/addons/web/static/tests/views/fields/email_field_tests.js +++ b/addons/web/static/tests/views/fields/email_field_tests.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { click, editInput, getFixture } from "@web/../tests/helpers/utils"; +import { click, clickSave, editInput, getFixture } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; let serverData; @@ -58,13 +58,8 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - let mailtoLink = target.querySelector(".o_field_email a.o_form_uri.o_text_overflow"); - assert.containsOnce(target, mailtoLink, "should have a anchor with correct classes"); - assert.strictEqual(mailtoLink.textContent, "yop", "the value should be displayed properly"); - assert.hasAttrValue(mailtoLink, "href", "mailto:yop", "should have proper mailto prefix"); // switch to edit mode and check the result - await click(target.querySelector(".o_form_button_edit")); const mailtoEdit = target.querySelector('.o_field_email input[type="email"]'); assert.containsOnce(target, mailtoEdit, "should have an input for the email field"); assert.strictEqual( @@ -77,15 +72,9 @@ QUnit.module("Fields", (hooks) => { await editInput(target, ".o_field_email input[type='email']", "new"); // save - await click(target.querySelector(".o_form_button_save")); - mailtoLink = target.querySelector(".o_field_email a"); - assert.strictEqual(mailtoLink.textContent, "new", "new value should be displayed properly"); - assert.hasAttrValue( - mailtoLink, - "href", - "mailto:new", - "should still have proper mailto prefix" - ); + await clickSave(target); + const mailtoLink = target.querySelector(".o_field_email input[type='email']"); + assert.strictEqual(mailtoLink.value, "new", "new value should be displayed properly"); }); QUnit.test("EmailField in editable list view", async function (assert) { @@ -132,7 +121,7 @@ QUnit.module("Fields", (hooks) => { await editInput(cell, "input", "new"); // save - await click(target.querySelector(".o_list_button_save")); + await clickSave(target); cell = target.querySelector("tbody td:not(.o_list_record_selector)"); assert.doesNotHaveClass( cell.parentElement, @@ -168,11 +157,9 @@ QUnit.module("Fields", (hooks) => { `, }); - assert.strictEqual(target.querySelector(".o_field_email input").placeholder, "Placeholder"); - - await click(target.querySelector(".o_form_button_save")); - const mailtoLink = target.querySelector(".o_field_email a"); - assert.strictEqual(mailtoLink.textContent, "", "the value should be displayed properly"); + const input = target.querySelector(".o_field_email input"); + assert.strictEqual(input.placeholder, "Placeholder"); + assert.strictEqual(input.value, "", "the value should be displayed properly"); }); QUnit.test("EmailField trim user value", async function (assert) { @@ -184,8 +171,7 @@ QUnit.module("Fields", (hooks) => { }); await editInput(target, ".o_field_widget[name='foo'] input", " abc@abc.com "); const mailFieldInput = target.querySelector('.o_field_widget[name="foo"] input'); - await click(target.querySelector(".o_form_button_save")); - await click(target.querySelector(".o_form_button_edit")); + await clickSave(target); assert.strictEqual( mailFieldInput.value, "abc@abc.com", @@ -229,7 +215,6 @@ QUnit.module("Fields", (hooks) => { ); // edit the phone field, but with the mail in readonly mode - await click(target.querySelector(".o_form_button_edit")); await editInput(target, ".o_field_widget[name='int_field'] input", 3); // check rendering after changes diff --git a/addons/web/static/tests/views/fields/float_factor_field_tests.js b/addons/web/static/tests/views/fields/float_factor_field_tests.js index ff5ebeff88a..3e0ec00ac5e 100644 --- a/addons/web/static/tests/views/fields/float_factor_field_tests.js +++ b/addons/web/static/tests/views/fields/float_factor_field_tests.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { click, editInput, getFixture } from "@web/../tests/helpers/utils"; +import { clickSave, editInput, getFixture } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; let serverData; @@ -25,7 +25,7 @@ QUnit.module("Fields", (hooks) => { QUnit.module("FloatFactorField"); QUnit.test("FloatFactorField in form view", async function (assert) { - assert.expect(4); + assert.expect(3); await makeView({ type: "form", @@ -45,13 +45,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "4.55", // 9.1 / 0.5 - "The formatted value should be displayed properly." - ); - - await click(target, ".o_form_button_edit"); assert.strictEqual( target.querySelector(".o_field_widget[name='qux'] input").value, "4.55", @@ -59,10 +52,10 @@ QUnit.module("Fields", (hooks) => { ); await editInput(target, ".o_field_widget[name='qux'] input", "2.3"); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "2.30", "The new value should be saved and displayed properly." ); diff --git a/addons/web/static/tests/views/fields/float_field_tests.js b/addons/web/static/tests/views/fields/float_field_tests.js index 6a84d68e00e..478825efa80 100644 --- a/addons/web/static/tests/views/fields/float_field_tests.js +++ b/addons/web/static/tests/views/fields/float_field_tests.js @@ -1,7 +1,7 @@ /** @odoo-module **/ import { makeFakeLocalizationService } from "@web/../tests/helpers/mock_services"; -import { click, editInput, getFixture, triggerEvent } from "@web/../tests/helpers/utils"; +import { click, clickSave, editInput, getFixture, triggerEvent } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; import { registry } from "@web/core/registry"; @@ -50,7 +50,7 @@ QUnit.module("Fields", (hooks) => { ); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "0.00", "Non-set float field should be considered as 0." ); @@ -68,7 +68,7 @@ QUnit.module("Fields", (hooks) => { }); assert.strictEqual( - target.querySelector(".o_field_float").textContent, + target.querySelector(".o_field_float input").value, "0.4", "should contain a number rounded to 1 decimal" ); @@ -84,7 +84,7 @@ QUnit.module("Fields", (hooks) => { }); assert.strictEqual( - target.querySelector(".o_field_float").textContent, + target.querySelector(".o_field_float input").value, "0.4", "should contain a number rounded to 1 decimal" ); @@ -100,7 +100,7 @@ QUnit.module("Fields", (hooks) => { }); assert.strictEqual( - target.querySelector(".o_field_float").textContent, + target.querySelector(".o_field_float input").value, "0.4", "should contain a number rounded to 1 decimal" ); @@ -115,8 +115,6 @@ QUnit.module("Fields", (hooks) => { arch: `
`, }); - await click(target, ".o_form_button_edit"); - assert.ok( target.querySelector(".o_field_widget input").hasAttribute("step"), "Integer field with option type must have a step attribute." @@ -145,19 +143,11 @@ QUnit.module("Fields", (hooks) => { "Float field should be considered set for value 0." ); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "0.000", "The value should be displayed properly." ); - await click(target, ".o_form_button_edit"); - - assert.strictEqual( - target.querySelector(".o_field_widget[name=float_field] input").value, - "0.000", - "The value should be rendered with correct precision." - ); - await editInput(target, 'div[name="float_field"] input', "108.2451938598598"); assert.strictEqual( target.querySelector(".o_field_widget[name=float_field] input").value, @@ -166,10 +156,10 @@ QUnit.module("Fields", (hooks) => { ); await editInput(target, ".o_field_widget[name=float_field] input", "18.8958938598598"); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "18.896", "The new value should be rounded properly." ); @@ -184,40 +174,36 @@ QUnit.module("Fields", (hooks) => { arch: `
`, }); - await click(target, ".o_form_button_edit"); await editInput(target, ".o_field_widget[name=float_field] input", "=20+3*2"); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "26.000", "The new value should be calculated properly." ); - await click(target, ".o_form_button_edit"); await editInput(target, ".o_field_widget[name=float_field] input", "=2**3"); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "8.000", "The new value should be calculated properly." ); - await click(target, ".o_form_button_edit"); await editInput(target, ".o_field_widget[name=float_field] input", "=2^3"); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "8.000", "The new value should be calculated properly." ); - await click(target, ".o_form_button_edit"); await editInput(target, ".o_field_widget[name=float_field] input", "=100/3"); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "33.333", "The new value should be calculated properly." ); @@ -232,9 +218,8 @@ QUnit.module("Fields", (hooks) => { arch: `
`, }); - await click(target, ".o_form_button_edit"); await editInput(target, ".o_field_widget[name=float_field] input", "=abc"); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.hasClass( target.querySelector(".o_field_widget[name=float_field]"), @@ -244,7 +229,7 @@ QUnit.module("Fields", (hooks) => { assert.containsOnce(target, ".o_form_editable", "form view should still be editable"); await editInput(target, ".o_field_widget[name=float_field] input", "=3:2?+4"); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.containsOnce(target, ".o_form_editable", "form view should still be editable"); assert.hasClass( @@ -291,32 +276,6 @@ QUnit.module("Fields", (hooks) => { ); }); - QUnit.test("do not trigger a field_changed if they have not changed", async function (assert) { - serverData.models.partner.records[0].float_field = false; - serverData.models.partner.records[0].int_field = false; - await makeView({ - serverData, - type: "form", - resModel: "partner", - arch: ` -
- - - - -
`, - mockRPC(route, { method }) { - assert.step(method); - }, - resId: 1, - }); - - await click(target.querySelector(".o_form_button_edit")); - await click(target.querySelector(".o_form_button_save")); - - assert.verifySteps(["get_views", "read"]); // should not have save as nothing changed - }); - QUnit.test("float field with type number option", async function (assert) { await makeView({ serverData, @@ -336,7 +295,6 @@ QUnit.module("Fields", (hooks) => { makeFakeLocalizationService({ thousandsSep: ",", grouping: [3, 0] }) ); - await click(target.querySelector(".o_form_button_edit")); assert.ok( target.querySelector(".o_field_widget input").hasAttribute("type"), "Float field with option type must have a type attribute." @@ -348,19 +306,12 @@ QUnit.module("Fields", (hooks) => { 'Float field with option type must have a type attribute equals to "number".' ); await editInput(target, ".o_field_widget[name=float_field] input", "123456.7890"); - await click(target.querySelector(".o_form_button_save")); - await click(target.querySelector(".o_form_button_edit")); + await clickSave(target); assert.strictEqual( target.querySelector(".o_field_widget input").value, "123456.789", "Float value must be not formatted if input type is number. (but the trailing 0 is gone)" ); - await click(target.querySelector(".o_form_button_save")); - assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "123,456.79", - "Float value must be formatted in readonly view even if the input type is number." - ); }); QUnit.test( @@ -386,7 +337,6 @@ QUnit.module("Fields", (hooks) => { }) ); - await click(target.querySelector(".o_form_button_edit")); assert.ok( target.querySelector(".o_field_widget input").hasAttribute("type"), "Float field with option type must have a type attribute." @@ -398,19 +348,12 @@ QUnit.module("Fields", (hooks) => { 'Float field with option type must have a type attribute equals to "number".' ); await editInput(target, ".o_field_widget[name=float_field] input", "123456.789"); - await click(target.querySelector(".o_form_button_save")); - await click(target.querySelector(".o_form_button_edit")); + await clickSave(target); assert.strictEqual( target.querySelector(".o_field_widget input").value, "123456.789", "Float value must be not formatted if input type is number." ); - await click(target.querySelector(".o_form_button_save")); - assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "123.456,79", - "Float value must be formatted in readonly view even if the input type is number." - ); } ); @@ -430,7 +373,6 @@ QUnit.module("Fields", (hooks) => { makeFakeLocalizationService({ thousandsSep: ",", grouping: [3, 0] }) ); - await click(target.querySelector(".o_form_button_edit")); assert.hasAttrValue( target.querySelector(".o_field_widget input"), "type", @@ -439,8 +381,7 @@ QUnit.module("Fields", (hooks) => { ); await editInput(target, ".o_field_widget[name=float_field] input", "123456.7890"); - await click(target.querySelector(".o_form_button_save")); - await click(target.querySelector(".o_form_button_edit")); + await clickSave(target); assert.strictEqual( target.querySelector(".o_field_widget input").value, "123,456.79", diff --git a/addons/web/static/tests/views/fields/float_time_field_tests.js b/addons/web/static/tests/views/fields/float_time_field_tests.js index e8aada0d09d..e9b9b59f313 100644 --- a/addons/web/static/tests/views/fields/float_time_field_tests.js +++ b/addons/web/static/tests/views/fields/float_time_field_tests.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { click, editInput, getFixture, triggerEvent } from "@web/../tests/helpers/utils"; +import { clickSave, editInput, getFixture, triggerEvent } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; let serverData; @@ -26,7 +26,7 @@ QUnit.module("Fields", (hooks) => { QUnit.module("FloatTimeField"); QUnit.test("FloatTimeField in form view", async function (assert) { - assert.expect(5); + assert.expect(4); await makeView({ serverData, @@ -52,13 +52,6 @@ QUnit.module("Fields", (hooks) => { }); // 9 + 0.1 * 60 = 9.06 - assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "09:06", - "The formatted time value should be displayed properly." - ); - - await click(target, ".o_form_button_edit"); assert.strictEqual( target.querySelector(".o_field_float_time[name=qux] input").value, "09:06", @@ -76,9 +69,9 @@ QUnit.module("Fields", (hooks) => { "The new value should be displayed properly in the input." ); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "-11:48", "The new value should be saved and displayed properly." ); @@ -108,12 +101,11 @@ QUnit.module("Fields", (hooks) => { }); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "09:06", "The formatted time value should be displayed properly." ); - await click(target, ".o_form_button_edit"); await editInput(target.querySelector(".o_field_float_time[name=qux] input"), null, "9.5"); assert.strictEqual( target.querySelector(".o_field_float_time[name=qux] input").value, @@ -121,9 +113,9 @@ QUnit.module("Fields", (hooks) => { "The new value should be displayed properly in the input." ); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "09:30", "The new value should be saved and displayed properly." ); @@ -145,7 +137,7 @@ QUnit.module("Fields", (hooks) => { null, "blabla" ); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( target.querySelector(".o_notification_title").textContent, "Invalid fields: " diff --git a/addons/web/static/tests/views/fields/float_toggle_field_tests.js b/addons/web/static/tests/views/fields/float_toggle_field_tests.js index 427c0c29b1a..76925189200 100644 --- a/addons/web/static/tests/views/fields/float_toggle_field_tests.js +++ b/addons/web/static/tests/views/fields/float_toggle_field_tests.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { click, clickEdit, clickSave, getFixture } from "@web/../tests/helpers/utils"; +import { click, clickSave, getFixture } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; let serverData; @@ -47,9 +47,6 @@ QUnit.module("Fields", (hooks) => { "0.056", // 0.4444 * 0.125 "The formatted time value should be displayed properly." ); - - await clickEdit(target); - assert.strictEqual( target.querySelector("button.o_field_float_toggle").textContent, "0.056", diff --git a/addons/web/static/tests/views/fields/handle_field_tests.js b/addons/web/static/tests/views/fields/handle_field_tests.js index 4d17d8b8797..b638af8041f 100644 --- a/addons/web/static/tests/views/fields/handle_field_tests.js +++ b/addons/web/static/tests/views/fields/handle_field_tests.js @@ -73,16 +73,13 @@ QUnit.module("Fields", (hooks) => { "handle should not have any content" ); - assert.strictEqual( - getComputedStyle(target.querySelector("td span.o_row_handle")).display, - "none", - "handle should be invisible in readonly mode" + assert.isVisible( + target.querySelector("td span.o_row_handle"), + "handle should be invisible" ); assert.containsN(target, "span.o_row_handle", 2, "should have 2 handles"); - await click(target, ".o_form_button_edit"); - assert.hasClass( target.querySelector("td"), "o_handle_cell", @@ -150,16 +147,7 @@ QUnit.module("Fields", (hooks) => { assert.strictEqual( getComputedStyle(target.querySelector("td span.o_row_handle")).display, "none", - "handle should be invisible in readonly mode" - ); - - await click(target, ".o_form_button_edit"); - - assert.containsN(target, ".o_row_handle", 3, "the handle fields should still be there"); - assert.strictEqual( - getComputedStyle(target.querySelector("td span.o_row_handle")).display, - "none", - "the handle icons should still not be displayed (on readonly fields)" + "handle should be invisible" ); }); }); diff --git a/addons/web/static/tests/views/fields/html_field_tests.js b/addons/web/static/tests/views/fields/html_field_tests.js index eccac230021..2ef1afd4acc 100644 --- a/addons/web/static/tests/views/fields/html_field_tests.js +++ b/addons/web/static/tests/views/fields/html_field_tests.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { click, editInput, getFixture } from "@web/../tests/helpers/utils"; +import { editInput, getFixture } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; import { registry } from "@web/core/registry"; import { HtmlField } from "@web/views/fields/html/html_field"; @@ -34,7 +34,21 @@ QUnit.module("Fields", ({ beforeEach }) => { QUnit.module("HtmlField"); - QUnit.test("html fields are correctly rendered", async (assert) => { + QUnit.test("html fields are correctly rendered (readonly)", async (assert) => { + await makeView({ + type: "form", + resModel: "partner", + resId: 1, + serverData, + arch: /* xml */ `
`, + }); + + assert.containsOnce(target, "div.kek"); + assert.strictEqual(target.querySelector(".o_field_html .kek").style.color, "red"); + assert.strictEqual(target.querySelector(".o_field_html").textContent, "some text"); + }); + + QUnit.test("html fields are correctly rendered (edit)", async (assert) => { await makeView({ type: "form", resModel: "partner", @@ -43,11 +57,6 @@ QUnit.module("Fields", ({ beforeEach }) => { arch: /* xml */ `
`, }); - assert.containsOnce(target, ".o_field_html", "should have a text area"); - assert.strictEqual(target.querySelector(".o_field_html .kek").style.color, "red"); - assert.strictEqual(target.querySelector(".o_field_html").textContent, "some text"); - - await click(target, ".o_form_button_edit"); const textarea = target.querySelector(".o_field_html textarea"); assert.ok(textarea, "should have a text area"); assert.strictEqual(textarea.value, RED_TEXT); @@ -58,10 +67,5 @@ QUnit.module("Fields", ({ beforeEach }) => { await editInput(textarea, null, BLUE_TEXT); assert.strictEqual(textarea.value, BLUE_TEXT); - - await click(target, ".o_form_button_save"); - - assert.strictEqual(target.querySelector(".o_field_html .kek").style.color, "blue"); - assert.strictEqual(target.querySelector(".o_field_html").textContent, "hello world"); }); }); diff --git a/addons/web/static/tests/views/fields/image_field_tests.js b/addons/web/static/tests/views/fields/image_field_tests.js index 510bf92807e..ce36b089db6 100644 --- a/addons/web/static/tests/views/fields/image_field_tests.js +++ b/addons/web/static/tests/views/fields/image_field_tests.js @@ -5,7 +5,6 @@ import { getFixture, nextTick, triggerEvent, - clickEdit, clickSave, editInput, } from "@web/../tests/helpers/utils"; @@ -131,8 +130,6 @@ QUnit.module("Fields", (hooks) => { "the image should correctly set its attributes" ); - await click(target, ".o_form_button_edit"); - assert.containsOnce( target, ".o_field_image .o_select_file_button", @@ -209,8 +206,6 @@ QUnit.module("Fields", (hooks) => { "the image should correctly set its attributes" ); - await click(target, ".o_form_button_edit"); - assert.containsOnce( target, ".o_field_image .o_select_file_button", @@ -241,7 +236,6 @@ QUnit.module("Fields", (hooks) => { "data:image/png;base64,coucou==", "the image should have the initial src" ); - await click(target, ".o_form_button_edit"); // Whitebox: replace the event target before the event is handled by the field so that we can modify // the files that it will take into account. This relies on the fact that it reads the files from // event.target and not from a direct reference to the input element. @@ -281,7 +275,6 @@ QUnit.module("Fields", (hooks) => { `, }); // The view must be in edit mode - await click(target.querySelector(".o_form_button_edit")); assert.strictEqual( target.querySelector("input.o_input_file").getAttribute("accept"), ".png,.jpeg", @@ -320,7 +313,7 @@ QUnit.module("Fields", (hooks) => { ); }); - QUnit.test("ImageField: zoom and zoom_delay options", async function (assert) { + QUnit.test("ImageField: zoom and zoom_delay options (readonly)", async (assert) => { serverData.models.partner.records[0].document = MY_IMAGE; await makeView({ @@ -330,7 +323,7 @@ QUnit.module("Fields", (hooks) => { serverData, arch: `
- + `, }); // data-tooltip attribute is used by the tooltip service @@ -344,8 +337,22 @@ QUnit.module("Fields", (hooks) => { "600", "tooltip has the right delay" ); + }); + + QUnit.test("ImageField: zoom and zoom_delay options (edit)", async function (assert) { + serverData.models.partner.records[0].document = MY_IMAGE; + + await makeView({ + type: "form", + resModel: "partner", + resId: 1, + serverData, + arch: ` +
+ + `, + }); - await click(target.querySelector(".o_form_button_edit")); assert.ok( !target.querySelector(".o_field_image img").dataset["tooltipInfo"], "the tooltip is not present in edition" @@ -353,7 +360,7 @@ QUnit.module("Fields", (hooks) => { }); QUnit.test( - "ImageField displays the right images with zoom and preview_image options", + "ImageField displays the right images with zoom and preview_image options (readonly)", async function (assert) { serverData.models.partner.records[0].document = "3 kb"; serverData.models.partner.records[0].__last_update = "2022-08-05 08:37:00"; @@ -365,7 +372,7 @@ QUnit.module("Fields", (hooks) => { serverData, arch: `
- + `, }); @@ -479,7 +486,7 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.containsOnce( target.querySelector(".o_form_view"), @@ -535,7 +542,6 @@ QUnit.module("Fields", (hooks) => { assert.verifySteps(["get_views", "read"]); assert.strictEqual(getUnique(target.querySelector(".o_field_image img")), "1659688620000"); - await clickEdit(target); assert.verifySteps([]); // same unique as before assert.strictEqual(getUnique(target.querySelector(".o_field_image img")), "1659688620000"); @@ -547,8 +553,8 @@ QUnit.module("Fields", (hooks) => { await clickSave(target); assert.verifySteps(["write", "read"]); - // different unique: the record has been written - assert.strictEqual(getUnique(target.querySelector(".o_field_image img")), "1659692220000"); + + assert.strictEqual(getUnique(target.querySelector(".o_field_image img")), "1659688620000"); }); QUnit.test("unique in url change on record change", async (assert) => { diff --git a/addons/web/static/tests/views/fields/image_url_field_tests.js b/addons/web/static/tests/views/fields/image_url_field_tests.js index 6545ec6f7fe..274562f0b5b 100644 --- a/addons/web/static/tests/views/fields/image_url_field_tests.js +++ b/addons/web/static/tests/views/fields/image_url_field_tests.js @@ -228,7 +228,7 @@ QUnit.module("Fields", (hooks) => { }); assert.hasClass( - target.querySelector('div[name="foo"].o_field_empty'), + target.querySelector('div[name="foo"]'), "o_field_image_url", "the widget should have the correct class" ); diff --git a/addons/web/static/tests/views/fields/integer_field_tests.js b/addons/web/static/tests/views/fields/integer_field_tests.js index c6001131d7a..7b8ef00acb4 100644 --- a/addons/web/static/tests/views/fields/integer_field_tests.js +++ b/addons/web/static/tests/views/fields/integer_field_tests.js @@ -4,6 +4,7 @@ import { localization } from "@web/core/l10n/localization"; import { defaultLocalization } from "@web/../tests/helpers/mock_services"; import { click, + clickSave, editInput, getFixture, patchWithCleanup, @@ -56,7 +57,7 @@ QUnit.module("Fields", (hooks) => { ); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "0", "Non-set integer field should be recognized as 0." ); @@ -71,8 +72,6 @@ QUnit.module("Fields", (hooks) => { arch: '
', }); - await click(target, ".o_form_button_edit"); - assert.strictEqual( target.querySelector(".o_field_widget[name=int_field] input").value, "10", @@ -87,10 +86,9 @@ QUnit.module("Fields", (hooks) => { "The value should be correctly displayed in the input." ); - await click(target, ".o_form_button_save"); - + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "30", "The new value should be saved and displayed properly." ); @@ -105,12 +103,11 @@ QUnit.module("Fields", (hooks) => { arch: '
', }); - await click(target, ".o_form_button_edit"); await editInput(target, ".o_field_widget[name=int_field] input", "=100/3"); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, + target.querySelector(".o_field_widget input").value, "33", "The new value should be calculated properly." ); @@ -127,8 +124,6 @@ QUnit.module("Fields", (hooks) => { arch: `
`, }); - await click(target, ".o_form_button_edit"); - assert.ok( target.querySelector(".o_field_widget input").hasAttribute("type"), "Integer field with option type must have a type attribute." @@ -142,22 +137,13 @@ QUnit.module("Fields", (hooks) => { ); await editInput(target, ".o_field_widget[name=int_field] input", "1234567890"); - await click(target, ".o_form_button_save"); - await click(target, ".o_form_button_edit"); + await clickSave(target); assert.strictEqual( target.querySelector(".o_field_widget input").value, "1234567890", "Integer value must be not formatted if input type is number." ); - - await click(target, ".o_form_button_save"); - - assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "1,234,567,890", - "Integer value must be formatted in readonly view even if the input type is number." - ); }); QUnit.test("with 'step' option", async function (assert) { @@ -169,13 +155,10 @@ QUnit.module("Fields", (hooks) => { arch: `
`, }); - await click(target, ".o_form_button_edit"); - assert.ok( target.querySelector(".o_field_widget input").hasAttribute("step"), "Integer field with option type must have a step attribute." ); - assert.hasAttrValue( target.querySelector(".o_field_widget input"), "step", @@ -195,8 +178,6 @@ QUnit.module("Fields", (hooks) => { arch: '
', }); - await click(target, ".o_form_button_edit"); - assert.hasAttrValue( target.querySelector(".o_field_widget input"), "type", @@ -205,8 +186,7 @@ QUnit.module("Fields", (hooks) => { ); await editInput(target, ".o_field_widget[name=int_field] input", "1234567890"); - await click(target, ".o_form_button_save"); - await click(target, ".o_form_button_edit"); + await clickSave(target); assert.strictEqual( target.querySelector(".o_field_widget input").value, @@ -224,14 +204,6 @@ QUnit.module("Fields", (hooks) => { arch: `
`, }); - assert.strictEqual( - target.querySelector(".o_field_widget[name=int_field]").textContent, - "8069", - "Integer value must not be formatted" - ); - - await click(target, ".o_form_button_edit"); - assert.strictEqual( target.querySelector(".o_field_widget input").value, "8069", @@ -250,14 +222,6 @@ QUnit.module("Fields", (hooks) => { arch: '
', }); - assert.strictEqual( - target.querySelector(".o_field_widget[name=int_field]").textContent, - "8,069", - "Integer value must be formatted by default" - ); - - await click(target, ".o_form_button_edit"); - assert.strictEqual( target.querySelector(".o_field_widget input").value, "8,069", diff --git a/addons/web/static/tests/views/fields/label_selection_field_tests.js b/addons/web/static/tests/views/fields/label_selection_field_tests.js index 73ef19c83d0..8b686dd979a 100644 --- a/addons/web/static/tests/views/fields/label_selection_field_tests.js +++ b/addons/web/static/tests/views/fields/label_selection_field_tests.js @@ -91,52 +91,6 @@ QUnit.module("Fields", (hooks) => { "Blocked", "the label should say 'Blocked' since this is the label value for that state" ); - - // // switch to edit mode and check the result - await click(target.querySelector(".o_form_button_edit")); - assert.containsOnce( - target, - ".o_field_widget .badge.text-bg-warning", - "should have a warning status label since selection is the second, blocked state" - ); - assert.containsNone( - target, - ".o_field_widget .badge.text-bg-secondary", - "should not have a default status since selection is the second, blocked state" - ); - assert.containsNone( - target, - ".o_field_widget .badge.text-bg-success", - "should not have a success status since selection is the second, blocked state" - ); - assert.strictEqual( - target.querySelector(".o_field_widget .badge.text-bg-warning").textContent, - "Blocked", - "the label should say 'Blocked' since this is the label value for that state" - ); - - // save - await click(target.querySelector(".o_form_button_save")); - assert.containsOnce( - target, - ".o_field_widget .badge.text-bg-warning", - "should have a warning status label since selection is the second, blocked state" - ); - assert.containsNone( - target, - ".o_field_widget .badge.text-bg-secondary", - "should not have a default status since selection is the second, blocked state" - ); - assert.containsNone( - target, - ".o_field_widget .badge.text-bg-success", - "should not have a success status since selection is the second, blocked state" - ); - assert.strictEqual( - target.querySelector(".o_field_widget .badge.text-bg-warning").textContent, - "Blocked", - "the label should say 'Blocked' since this is the label value for that state" - ); }); QUnit.test("LabelSelectionField in editable list view", async function (assert) { diff --git a/addons/web/static/tests/views/fields/many2many_binary_field_tests.js b/addons/web/static/tests/views/fields/many2many_binary_field_tests.js index 1737efc4c98..796327e478b 100644 --- a/addons/web/static/tests/views/fields/many2many_binary_field_tests.js +++ b/addons/web/static/tests/views/fields/many2many_binary_field_tests.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { click, getFixture, nextTick } from "@web/../tests/helpers/utils"; +import { click, clickSave, getFixture, nextTick } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; import { registry } from "@web/core/registry"; @@ -111,19 +111,17 @@ QUnit.module("Fields", (hooks) => { "div.o_field_widget .oe_fileupload .o_attachments", "there should be one attachment" ); - assert.containsNone( + assert.containsOnce( target, "div.o_field_widget .oe_fileupload .o_attach", - "there should not be an Add button (readonly)" + "there should be an Add button (edit)" ); - assert.containsNone( + assert.containsOnce( target, "div.o_field_widget .oe_fileupload .o_attachment .o_attachment_delete", - "there should not be a Delete button (readonly)" + "there should be a Delete button (edit)" ); - // to edit mode - await click(target, ".o_form_button_edit"); assert.containsOnce( target, "div.o_field_widget .oe_fileupload .o_attach", @@ -176,7 +174,7 @@ QUnit.module("Fields", (hooks) => { ) ); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.containsOnce( target, "div.o_field_widget .oe_fileupload .o_attachments", @@ -251,20 +249,17 @@ QUnit.module("Fields", (hooks) => { "div.o_field_widget .oe_fileupload .o_attachments", "there should be one attachment" ); - assert.containsNone( + assert.containsOnce( target, "div.o_field_widget .oe_fileupload .o_attach", - "there should not be an Add button (readonly)" + "there should be an Add button (edit)" ); - assert.containsNone( + assert.containsOnce( target, "div.o_field_widget .oe_fileupload .o_attachment .o_attachment_delete", - "there should not be a Delete button (readonly)" + "there should be a Delete button (edit)" ); - // to edit mode - await click(target, ".o_form_button_edit"); - // Set and trigger the import of 2 files in the input const fileInput = target.querySelector('input[type="file"]'); const dataTransfer = new DataTransfer(); diff --git a/addons/web/static/tests/views/fields/many2many_checkboxes_field_tests.js b/addons/web/static/tests/views/fields/many2many_checkboxes_field_tests.js index 5059e041bb5..9acd753e8ea 100644 --- a/addons/web/static/tests/views/fields/many2many_checkboxes_field_tests.js +++ b/addons/web/static/tests/views/fields/many2many_checkboxes_field_tests.js @@ -67,22 +67,17 @@ QUnit.module("Fields", (hooks) => { assert.ok(checkboxes[0].checked); assert.notOk(checkboxes[1].checked); - assert.containsN(target, "div.o_field_widget div.form-check input:disabled", 2); - - await click(target, ".o_form_button_edit"); - assert.containsNone(target, "div.o_field_widget div.form-check input:disabled"); // add a m2m value by clicking on input checkboxes = target.querySelectorAll("div.o_field_widget div.form-check input"); await click(checkboxes[1]); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.containsN(target, "div.o_field_widget div.form-check input:checked", 2); // remove a m2m value by clinking on label - await click(target, ".o_form_button_edit"); await click(target.querySelector("div.o_field_widget div.form-check > label")); - await click(target, ".o_form_button_save"); + await clickSave(target); checkboxes = target.querySelectorAll("div.o_field_widget div.form-check input"); assert.notOk(checkboxes[0].checked); assert.ok(checkboxes[1].checked); @@ -111,25 +106,6 @@ QUnit.module("Fields", (hooks) => { 2, "should have fetched and displayed the 2 values of the many2many" ); - - assert.ok( - target.querySelector("div.o_field_widget div.form-check input").checked, - "first checkbox should be checked" - ); - assert.notOk( - target.querySelectorAll("div.o_field_widget div.form-check input")[1].checked, - "second checkbox should not be checked" - ); - - assert.containsN( - target, - "div.o_field_widget div.form-check input:disabled", - 2, - "the checkboxes should be disabled" - ); - - await click(target, ".o_form_button_edit"); - assert.containsN( target, "div.o_field_widget div.form-check input:disabled", @@ -166,11 +142,9 @@ QUnit.module("Fields", (hooks) => { `, }); - await click(target, ".o_form_button_edit"); - await click(target.querySelectorAll("div.o_field_widget div.form-check input")[0]); await click(target.querySelectorAll("div.o_field_widget div.form-check input")[1]); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.notOk( target.querySelectorAll("div.o_field_widget div.form-check input")[0].checked, "first checkbox should not be checked" @@ -197,8 +171,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await click(target, ".o_form_button_edit"); - assert.strictEqual( target.querySelector(".o_field_widget[name='int_field'] input").value, "10" @@ -255,8 +227,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); - assert.containsN( target, ".o_field_widget[name='timmy'] input[type='checkbox']:checked", @@ -269,7 +239,7 @@ QUnit.module("Fields", (hooks) => { ); await click(checkboxes[checkboxes.length - 1]); - await click(target, ".o_form_button_save"); + await clickSave(target); checkboxes = target.querySelectorAll( ".o_field_widget[name='timmy'] input[type='checkbox']" ); @@ -316,8 +286,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); - assert.containsN( target, ".o_field_widget[name='timmy'] input[type='checkbox']", @@ -331,7 +299,7 @@ QUnit.module("Fields", (hooks) => { // toggle the first value await click(target.querySelector(".o_field_widget[name='timmy'] input[type='checkbox']")); - await click(target, ".o_form_button_save"); + await clickSave(target); assert.notOk( target.querySelector(".o_field_widget[name='timmy'] input[type='checkbox']").checked ); @@ -367,7 +335,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await click(target, ".o_form_button_edit"); await click(target.querySelector(".o_data_cell")); // edit the timmy field by (un)checking boxes on the widget @@ -379,7 +346,7 @@ QUnit.module("Fields", (hooks) => { assert.notOk(secondCheckbox.checked, "the checkbox should be unticked"); await click(target.querySelector(".modal .o_form_button_save")); - await click(target.querySelector(".o_form_button_save")); + await clickSave(target); }); QUnit.test("Many2ManyCheckBoxesField with default values", async function (assert) { diff --git a/addons/web/static/tests/views/fields/many2many_field_tests.js b/addons/web/static/tests/views/fields/many2many_field_tests.js index 6e1de164f77..3f4bc49f5c8 100644 --- a/addons/web/static/tests/views/fields/many2many_field_tests.js +++ b/addons/web/static/tests/views/fields/many2many_field_tests.js @@ -4,7 +4,6 @@ import { browser } from "@web/core/browser/browser"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; import { click, - clickEdit, clickSave, clickOpenedDropdownItem, editInput, @@ -223,7 +222,7 @@ QUnit.module("Fields", (hooks) => { QUnit.module("Many2ManyField"); QUnit.test("many2many kanban: edition", async function (assert) { - assert.expect(33); + assert.expect(31); serverData.views = { "partner_type,false,form": '
', @@ -296,17 +295,6 @@ QUnit.module("Fields", (hooks) => { }, }); - assert.ok( - !$(target).find(".o_kanban_renderer .delete_icon").length, - "delete icon should not be visible in readonly" - ); - assert.ok( - !$(target).find(".o_field_many2many .o-kanban-button-new").length, - '"Add" button should not be visible in readonly' - ); - - await clickEdit(target); - assert.strictEqual( $(target).find(".o_kanban_record:not(.o_kanban_ghost)").length, 2, @@ -467,7 +455,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); assert.strictEqual( target .querySelector(".o_field_many2many[name=timmy] .o-kanban-button-new") @@ -549,13 +536,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - assert.ok( - !$(target).find(".o-kanban-button-new").length, - '"Add" button should not be available in readonly' - ); - - await clickEdit(target); - assert.ok( $(target).find(".o-kanban-button-new").length, '"Add" button should be available in edit' @@ -603,7 +583,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); // color is red assert.containsOnce(target, ".o-kanban-button-new", '"Add" button should be available'); @@ -653,7 +632,7 @@ QUnit.module("Fields", (hooks) => { }); QUnit.test("many2many list (non editable): edition", async function (assert) { - assert.expect(34); + assert.expect(32); serverData.models.partner.records[0].timmy = [12, 14]; serverData.models.partner_type.records.push({ id: 15, display_name: "bronze", color: 6 }); @@ -693,18 +672,6 @@ QUnit.module("Fields", (hooks) => { "read", // main record "read", // relational field ]); - assert.containsNone( - target, - ".o_list_record_remove", - "delete icon should not be visible in readonly" - ); - assert.containsNone( - target, - ".o_field_x2many_list_row_add", - '"Add an item" should not be visible in readonly' - ); - - await clickEdit(target); assert.containsN( target, @@ -842,7 +809,7 @@ QUnit.module("Fields", (hooks) => { }); QUnit.test("many2many list (editable): edition", async function (assert) { - assert.expect(31); + assert.expect(29); serverData.models.partner.records[0].timmy = [12, 14]; serverData.models.partner_type.records.push({ id: 15, display_name: "bronze", color: 6 }); @@ -879,11 +846,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - assert.containsNone(target, ".o_list_record_remove"); - assert.containsNone(target, ".o_field_x2many_list_row_add"); - - await clickEdit(target); - assert.containsN( target, ".o_list_renderer td.o_list_number", @@ -1020,8 +982,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); - assert.containsOnce( target, ".o_field_x2many_list_row_add", @@ -1048,8 +1008,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); - assert.containsOnce( target, ".o_field_x2many_list_row_add", @@ -1079,8 +1037,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - assert.containsNone(target, ".o_field_x2many_list_row_add"); - await clickEdit(target); assert.containsOnce(target, ".o_field_x2many_list_row_add"); }); @@ -1138,7 +1094,6 @@ QUnit.module("Fields", (hooks) => { assert.containsOnce(target, ".o_field_many2many .o_field_x2many_list_row_add"); await clickSave(target); - await clickEdit(target); assert.containsOnce(target, ".o_field_many2many .o_data_row .o_list_record_remove"); await click(target.querySelector(".o_field_many2many .o_data_row .o_list_record_remove")); @@ -1169,8 +1124,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); - // color is red -> create and delete actions are available assert.containsOnce( target, @@ -1239,8 +1192,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); - // color is red -> link and unlink actions are available assert.containsOnce( target, @@ -1300,8 +1251,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); - // color is red -> link and unlink actions are available assert.containsOnce( target, @@ -1364,7 +1313,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); // color is red -> link and unlink actions are available assert.containsOnce(target, ".o-kanban-button-new", "should have the 'Add' button"); @@ -1416,7 +1364,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); // color is red -> link and unlink actions are available assert.containsOnce(target, ".o-kanban-button-new", "should have the 'Add' button"); @@ -1502,8 +1449,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); - await click(target.querySelector(".o_field_x2many_list_row_add a")); await click($(target).find(".modal .o_data_row:first .o_data_cell")[0]); @@ -1569,7 +1514,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); await click(target.querySelector(".o_field_x2many_list_row_add a")); assert.strictEqual($(".modal .o_data_row").length, 1, "should contain only one row (gold)"); @@ -1608,7 +1552,6 @@ QUnit.module("Fields", (hooks) => { }); assert.verifySteps(["get_views", "read", "read"]); - await clickEdit(target); await click($(target).find("td.o_data_cell:first")[0]); assert.verifySteps(["get_views", "read"]); @@ -1671,8 +1614,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); - assert.verifySteps(["get_views", "read"]); await editInput(target, ".o_field_widget[name=foo] input", "trigger onchange"); @@ -1823,7 +1764,6 @@ QUnit.module("Fields", (hooks) => { }); // First round: add 51 records in batch - await clickEdit(target); await click(target.querySelector(".o_field_x2many_list_row_add a")); var $modal = $(".modal-lg"); @@ -1844,7 +1784,6 @@ QUnit.module("Fields", (hooks) => { await clickSave(target); // Secound round: remove one record - await clickEdit(target); var trash_buttons = $(target).find( ".o_field_many2many.o_field_widget .o_field_x2many.o_field_x2many_list .o_list_record_remove" ); @@ -1942,7 +1881,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await clickEdit(target); await click(target, ".o_field_many2many_selection input"); checkGetViews = true; await clickOpenedDropdownItem(target, "timmy", "Search More..."); @@ -2000,6 +1938,7 @@ QUnit.module("Fields", (hooks) => { await click(target.querySelector(".o_data_cell")); await editInput(target, ".o_field_many2many_selection input", "indianapolis"); + await nextTick(); await clickOpenedDropdownItem(target, "timmy", "Create and edit..."); assert.containsOnce(target, ".modal .o_field_many2one"); assert.strictEqual( @@ -2055,8 +1994,8 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await editInput(target, ".o_field_many2many_selection input", "indianapolis"); + await nextTick(); await clickOpenedDropdownItem(target, "timmy", "Create and edit..."); assert.containsOnce(target, ".modal .o_field_many2one"); assert.strictEqual( @@ -2120,7 +2059,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await click(target, ".o_data_cell"); await editInput(target, ".o_field_many2many_selection input", "indianapolis"); await clickOpenedDropdownItem(target, "timmy", "Create and edit..."); diff --git a/addons/web/static/tests/views/fields/many2many_tags_avatar_field_tests.js b/addons/web/static/tests/views/fields/many2many_tags_avatar_field_tests.js index 00abfbaf44e..71ddfc2d1c2 100644 --- a/addons/web/static/tests/views/fields/many2many_tags_avatar_field_tests.js +++ b/addons/web/static/tests/views/fields/many2many_tags_avatar_field_tests.js @@ -1,12 +1,6 @@ /** @odoo-module **/ -import { - click, - clickEdit, - clickSave, - getFixture, - selectDropdownItem, -} from "@web/../tests/helpers/utils"; +import { click, clickSave, getFixture, selectDropdownItem } from "@web/../tests/helpers/utils"; import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; let serverData; @@ -206,12 +200,12 @@ QUnit.module("Fields", (hooks) => { assert.strictEqual( tag.dataset["tooltipTemplate"], "web.TagsList.Tooltip", - "uses the proper tooltip template", + "uses the proper tooltip template" ); const tooltipInfo = JSON.parse(tag.dataset["tooltipInfo"]); assert.strictEqual( - tooltipInfo.tags.map(tag => tag.text).join(" "), - 'record 6 record 7', + tooltipInfo.tags.map((tag) => tag.text).join(" "), + "record 6 record 7", "shows a tooltip on hover" ); @@ -363,12 +357,12 @@ QUnit.module("Fields", (hooks) => { assert.strictEqual( tag.dataset["tooltipTemplate"], "web.TagsList.Tooltip", - "uses the proper tooltip template", + "uses the proper tooltip template" ); const tooltipInfo = JSON.parse(tag.dataset["tooltipInfo"]); assert.strictEqual( - tooltipInfo.tags.map(tag => tag.text).join(" "), - 'aaa record 5', + tooltipInfo.tags.map((tag) => tag.text).join(" "), + "aaa record 5", "shows a tooltip on hover" ); @@ -391,7 +385,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await clickEdit(target); assert.containsN( target, ".o_field_many2many_tags_avatar.o_field_widget .badge", diff --git a/addons/web/static/tests/views/fields/many2many_tags_field_tests.js b/addons/web/static/tests/views/fields/many2many_tags_field_tests.js index 7cccd6f41f5..32ace21498f 100644 --- a/addons/web/static/tests/views/fields/many2many_tags_field_tests.js +++ b/addons/web/static/tests/views/fields/many2many_tags_field_tests.js @@ -6,7 +6,6 @@ import { Many2ManyTagsField } from "@web/views/fields/many2many_tags/many2many_t import { click, clickDropdown, - clickEdit, clickOpenedDropdownItem, clickSave, editInput, @@ -162,7 +161,7 @@ QUnit.module("Fields", (hooks) => { }); QUnit.test("Many2ManyTagsField with color: rendering and edition", async function (assert) { - assert.expect(28); + assert.expect(26); serverData.models.partner.records[0].timmy = [12, 14]; serverData.models.partner_type.records.push({ id: 13, display_name: "red", color: 8 }); @@ -211,19 +210,6 @@ QUnit.module("Fields", (hooks) => { "o_tag_color_2", "should have correctly set the color" ); - - await clickEdit(target); - - assert.containsN( - target, - ".o_field_many2many_tags .badge", - 2, - "should still contain 2 tags in edit mode" - ); - assert.ok( - target.querySelector(".o_tag_color_2 .o_tag_badge_text").textContent === "gold", - 'first tag should still contain "gold" and be color 2 in edit mode' - ); assert.containsN( target, ".o_field_many2many_tags .o_delete", @@ -274,7 +260,7 @@ QUnit.module("Fields", (hooks) => { `should not contain tag 'silver' anymore but found: ${textContent}` ); // save the record (should do the write RPC with the correct commands) - await click(target.querySelector(".o_form_button_save")); + await clickSave(target); // checkbox 'Hide in Kanban' const badgeElement = target.querySelectorAll(".o_field_many2many_tags .badge")[1]; // selects 'red' tag @@ -426,8 +412,6 @@ QUnit.module("Fields", (hooks) => { "should have fetched and rendered gold partner tag" ); - await clickEdit(target); - await clickDropdown(target, "timmy"); const autocompleteDropdown = target.querySelector(".o-autocomplete--dropdown-menu"); @@ -540,7 +524,6 @@ QUnit.module("Fields", (hooks) => { ); // Update the color in edit => write on save with rest of the record - await clickEdit(target); await click(badgeNode); await click(target, '.o_colorlist button[data-color="6"]'); await nextTick(); @@ -727,7 +710,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); assert.containsOnce(target, ".o_field_many2many_tags .badge", "should contain one tag"); // update foo, which will trigger an onchange and update timmy @@ -840,8 +822,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); - assert.strictEqual( target.querySelectorAll(".o_field_many2many_tags .badge").length, 1, @@ -913,7 +893,7 @@ QUnit.module("Fields", (hooks) => { assert.containsOnce(target, ".o_field_many2many_tags .badge"); - await click(target.querySelector(".o_form_button_save")); + await clickSave(target); assert.strictEqual( target.querySelector(".o_field_many2many_tags").textContent.trim(), @@ -986,7 +966,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); assert.deepEqual( getNodesTextContent(target.querySelectorAll(".o_data_cell")), ["second recordaaa"], @@ -1027,7 +1006,6 @@ QUnit.module("Fields", (hooks) => { }); assert.verifySteps(["world"]); - await clickEdit(target); await selectDropdownItem(target, "timmy", "silver"); assert.verifySteps(["world"]); }); @@ -1056,7 +1034,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await clickEdit(target); await selectDropdownItem(target, "timmy", "Search More..."); assert.ok(target.querySelector(".o_dialog"), "should have open the modal"); @@ -1113,7 +1090,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await clickEdit(target); await selectDropdownItem(target, "timmy", "Search More..."); // -1 for the one that is already on the form & +1 for the select all, @@ -1172,7 +1148,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await clickEdit(target); await editInput(target, `div[name="timmy"] input`, "Ralts"); await nameSearchProm; @@ -1244,8 +1219,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); - await editInput(target, ".o_field_widget input", "hello"); await nameSearchProm; await nextTick(); @@ -1301,8 +1274,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); - // turtle_bar is true -> create and delete actions are available assert.containsOnce( target, diff --git a/addons/web/static/tests/views/fields/many2one_avatar_field_tests.js b/addons/web/static/tests/views/fields/many2one_avatar_field_tests.js index 8d857f7c2fa..514e7490bf1 100644 --- a/addons/web/static/tests/views/fields/many2one_avatar_field_tests.js +++ b/addons/web/static/tests/views/fields/many2one_avatar_field_tests.js @@ -3,7 +3,6 @@ import { browser } from "@web/core/browser/browser"; import { click, - clickEdit, clickSave, editInput, getFixture, @@ -78,7 +77,7 @@ QUnit.module("Fields", (hooks) => { }); assert.strictEqual( - target.querySelector(".o_field_widget[name=user_id]").textContent.trim(), + target.querySelector(".o_field_widget[name=user_id] input").value, "Aline" ); assert.containsOnce( @@ -86,8 +85,6 @@ QUnit.module("Fields", (hooks) => { '.o_m2o_avatar > img[data-src="/web/image/user/17/avatar_128"]' ); - await clickEdit(target); - assert.containsOnce(target, ".o_input_dropdown"); assert.strictEqual(target.querySelector(".o_input_dropdown input").value, "Aline"); assert.containsOnce(target, ".o_external_button"); @@ -105,7 +102,7 @@ QUnit.module("Fields", (hooks) => { await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget[name=user_id]").textContent.trim(), + target.querySelector(".o_field_widget[name=user_id] input").value, "Christine" ); assert.containsOnce( @@ -113,7 +110,6 @@ QUnit.module("Fields", (hooks) => { '.o_m2o_avatar > img[data-src="/web/image/user/19/avatar_128"]' ); - await clickEdit(target); await editInput(target, '.o_field_widget[name="user_id"] input', ""); assert.containsNone(target, ".o_m2o_avatar > img"); @@ -121,7 +117,7 @@ QUnit.module("Fields", (hooks) => { await clickSave(target); assert.containsNone(target, ".o_m2o_avatar > img"); - assert.containsNone(target, ".o_m2o_avatar > .o_m2o_avatar_empty"); + assert.containsOnce(target, ".o_m2o_avatar > .o_m2o_avatar_empty"); }); QUnit.test("onchange in form view flow", async function (assert) { diff --git a/addons/web/static/tests/views/fields/many2one_field_tests.js b/addons/web/static/tests/views/fields/many2one_field_tests.js index bc1163f45c0..13b1bd742d7 100644 --- a/addons/web/static/tests/views/fields/many2one_field_tests.js +++ b/addons/web/static/tests/views/fields/many2one_field_tests.js @@ -10,7 +10,6 @@ import { click, clickDiscard, clickDropdown, - clickEdit, clickOpenedDropdownItem, clickSave, dragAndDrop, @@ -214,7 +213,7 @@ QUnit.module("Fields", (hooks) => { QUnit.module("Many2oneField"); QUnit.test("many2ones in form views", async function (assert) { - assert.expect(5); + assert.expect(2); function createMockActionService(assert) { return { @@ -253,7 +252,7 @@ QUnit.module("Fields", (hooks) => {
- +
`, @@ -278,11 +277,6 @@ QUnit.module("Fields", (hooks) => { }, }); - assert.containsOnce(target, "a.o_form_uri:contains(aaa)", "should contain a link"); - await click(target, "a.o_form_uri"); - - await click(target, ".o_form_button_edit"); - await click(target, ".o_external_button"); assert.strictEqual( target.querySelector(".modal .modal-title").textContent.trim(), @@ -313,7 +307,7 @@ QUnit.module("Fields", (hooks) => { arch: `
- +
`, mockRPC(route, { args, method }) { @@ -324,8 +318,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); - // click on the external button (should do an RPC) await click(target, ".o_external_button"); // save and close modal @@ -390,7 +382,7 @@ QUnit.module("Fields", (hooks) => { arch: `
- +
`, mockRPC(route, { method }) { @@ -400,8 +392,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); - // click on the external button (should do an RPC) await click(target, ".o_external_button"); @@ -412,7 +402,7 @@ QUnit.module("Fields", (hooks) => { // save and close modal await clickSave(target.querySelector(".modal")); // save form - await click(target, ".o_form_button_save"); + await clickSave(target); // click next on pager await click(target, ".o_pager .o_pager_next"); @@ -447,13 +437,6 @@ QUnit.module("Fields", (hooks) => { }, }); - assert.strictEqual( - target.querySelector("a.o_form_uri").innerHTML, - "aaa
Street
City ZIP", - "input should have a multi-line content in readonly due to show_address" - ); - - await click(target, ".o_form_button_edit"); assert.strictEqual(target.querySelector("input.o_input").value, "aaa"); assert.strictEqual( target.querySelector(".o_field_many2one_extra").innerHTML, @@ -493,7 +476,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); const input = target.querySelector(".o_field_widget input"); assert.strictEqual(input.value, "aaa"); @@ -543,7 +525,7 @@ QUnit.module("Fields", (hooks) => { serverData, resId: 1, arch: ` -
+ `, @@ -587,7 +569,7 @@ QUnit.module("Fields", (hooks) => { serverData, resId: 1, arch: ` -
+ `, @@ -644,8 +626,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await click(target, ".o_form_button_edit"); - await selectDropdownItem(target, "trululu", "Search More..."); assert.strictEqual($("tr.o_data_row").length, 9, "should display 9 records"); @@ -754,7 +734,7 @@ QUnit.module("Fields", (hooks) => { QUnit.test( "onchanges on many2ones trigger when editing record in form view", async function (assert) { - assert.expect(11); + assert.expect(10); serverData.models.partner.onchanges.user_id = function () {}; serverData.models.user.fields.other_field = { string: "Other Field", type: "char" }; @@ -774,7 +754,7 @@ QUnit.module("Fields", (hooks) => {
- +
`, @@ -794,7 +774,6 @@ QUnit.module("Fields", (hooks) => { }); // open the many2one in form view and change something - await click(target, ".o_form_button_edit"); await click(target, ".o_external_button"); await editInput( target, @@ -814,11 +793,6 @@ QUnit.module("Fields", (hooks) => { "read", "onchange", ]); - - // save the main record, and check that no extra rpcs are done (record - // is not dirty, only a related record was modified) - await click(target, ".o_form_button_save"); - assert.verifySteps([]); } ); @@ -938,14 +912,6 @@ QUnit.module("Fields", (hooks) => { `, }); - assert.containsOnce( - target, - ".o_field_widget[name='trululu'] > span", - "should be displayed inside a span (sanity check)" - ); - assert.containsNone(target, "span.o_form_uri", "should not have an anchor"); - - await click(target, ".o_form_button_edit"); assert.containsNone( target, ".o_field_widget[name='trululu'] .o_external_button", @@ -1086,14 +1052,12 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); - // trigger the onchange await editInput(target, ".o_field_widget[name='foo'] input", "3"); assert.verifySteps(["onchange"]); // save - await click(target, ".o_form_button_save"); + await clickSave(target); assert.verifySteps(["write"]); } ); @@ -1142,7 +1106,6 @@ QUnit.module("Fields", (hooks) => { // event to specify a fake session to prevent it from crashing patchWithCleanup(session.user_context, {}); - await click(target, ".o_form_button_edit"); await clickDropdown(target, "trululu"); let dropdown = target.querySelector(".o_field_many2one[name='trululu'] .dropdown-menu"); @@ -1229,22 +1192,22 @@ QUnit.module("Fields", (hooks) => { ); // save - await click(target, ".o_form_button_save"); + await clickSave(target); assert.strictEqual( - target.querySelector("a.o_form_uri").textContent, + target.querySelector(".o_field_many2one input").value, "Partner 20", "should display correct value after save" ); }); - QUnit.test("many2one in non edit mode", async function (assert) { + QUnit.test("many2one in non edit mode (with value)", async function (assert) { await makeView({ type: "form", resModel: "partner", resId: 1, serverData, arch: ` -
+ `, }); @@ -1256,12 +1219,23 @@ QUnit.module("Fields", (hooks) => { "#id=4&model=partner", "href should contain id and model" ); + }); + + QUnit.test("many2one in non edit mode (without value)", async function (assert) { + serverData.models.partner.records[0].trululu = false; + + await makeView({ + type: "form", + resModel: "partner", + resId: 1, + serverData, + arch: ` +
+ + `, + }); // Remove value from many2one and then save, there should be no link anymore - await click(target, ".o_form_button_edit"); - await editInput(target, ".o_field_many2one input", ""); - - await click(target, ".o_form_button_save"); assert.containsNone(target, "a.o_form_uri"); }); @@ -1320,7 +1294,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await click(target, ".o_form_button_edit"); assert.strictEqual( target.querySelector(".o_field_many2one input").value, @@ -1404,7 +1377,34 @@ QUnit.module("Fields", (hooks) => { assert.verifySteps(["search: ", "search: first", "search: first", "search: first"]); }); - QUnit.test("many2one field with option always_reload", async function (assert) { + QUnit.test("many2one field with option always_reload (readonly)", async function (assert) { + let count = 0; + await makeView({ + type: "form", + resModel: "partner", + resId: 2, + serverData, + arch: ` +
+ + `, + mockRPC(route, { method }) { + if (method === "name_get") { + count++; + return Promise.resolve([[1, "first record\nand some address"]]); + } + }, + }); + + assert.strictEqual(count, 1, "an extra name_get should have been done"); + assert.ok( + target.querySelector("a.o_form_uri").textContent.includes("and some address"), + "should display additional result" + ); + assert.containsNone(target, ".o_field_many2one_extra"); + }); + + QUnit.test("many2one field with option always_reload (edit)", async function (assert) { let count = 0; await makeView({ type: "form", @@ -1424,22 +1424,15 @@ QUnit.module("Fields", (hooks) => { }); assert.strictEqual(count, 1, "an extra name_get should have been done"); - assert.ok( - target.querySelector("a.o_form_uri").textContent.includes("and some address"), - "should display additional result" - ); - - await click(target, ".o_form_button_edit"); assert.strictEqual( target.querySelector(".o_field_widget[name='trululu'] input").value, "first record", "actual field value should be displayed to be edited" ); - - await click(target, ".o_form_button_save"); - assert.ok( - target.querySelector("a.o_form_uri").textContent.includes("and some address"), - "should still display additional result" + assert.containsOnce(target, ".o_field_many2one_extra"); + assert.strictEqual( + target.querySelector(".o_field_many2one_extra").textContent, + "and some address" ); }); @@ -2469,7 +2462,7 @@ QUnit.module("Fields", (hooks) => {
- +
`, @@ -2480,7 +2473,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await click(target.querySelector("td.o_data_cell")); await click(target, ".o_external_button"); assert.containsOnce(target, ".modal"); @@ -2568,7 +2560,7 @@ QUnit.module("Fields", (hooks) => { - + `, @@ -2593,7 +2585,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); await click(target, ".o_data_cell"); await click(target, ".o_external_button"); @@ -2634,8 +2625,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await click(target, ".o_form_button_edit"); - click(target, ".o_field_widget[name=product_id] input"); }); @@ -2661,8 +2650,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await click(target, ".o_form_button_edit"); - click(target, ".o_field_widget[name='trululu'] input"); } ); @@ -2738,11 +2725,10 @@ QUnit.module("Fields", (hooks) => { arch: '
', }); assert.strictEqual( - target.querySelector(".o_field_widget[name='product_id']").textContent, + target.querySelector(".o_field_widget[name='product_id'] input").value, "", "the tag a should be empty" ); - await click(target, ".o_form_button_edit"); await click(target, ".o_field_widget[name='product_id'] input"); await click(target.querySelector(".o_field_widget[name='product_id'] .dropdown-item")); @@ -2752,9 +2738,9 @@ QUnit.module("Fields", (hooks) => { "should have selected xphone" ); - await click(target, ".o_form_button_cancel"); + await clickDiscard(target); assert.strictEqual( - target.querySelector(".o_field_widget[name='product_id']").textContent, + target.querySelector(".o_field_widget[name='product_id'] input").value, "", "the tag a should be empty" ); @@ -2812,7 +2798,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); click(target, ".o_field_widget[name='product_id'] input"); click(target, ".o_field_widget[name='trululu'] input"); } @@ -3068,7 +3053,7 @@ QUnit.module("Fields", (hooks) => { arch: `
- +
`, mockRPC(route) { @@ -3150,7 +3135,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); await click(target.querySelector(".o_field_widget[name=product_id] input")); assert.containsNone(target, ".o-autocomplete a:contains(Start typing...)"); @@ -3321,8 +3305,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); - const input = target.querySelector(".o_field_many2one input"); await editInput(input, null, "first"); @@ -3395,8 +3377,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await click(target, ".o_form_button_edit"); - const input = target.querySelector(".o_field_many2one input"); assert.ok(input.value, "many2one should have value"); @@ -3580,8 +3560,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); - // trigger a name_search (domain should be []) await click(target, ".o_field_widget[name=trululu] input"); // close the dropdown @@ -3629,8 +3607,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await click(target, ".o_form_button_edit"); - // add a first row with a specific domain for the m2o domain = [["id", "in", [10]]]; // domain for subrecord 1 await click(target, ".o_field_x2many_list_row_add a"); @@ -3835,7 +3811,7 @@ QUnit.module("Fields", (hooks) => { - + `, @@ -3848,7 +3824,6 @@ QUnit.module("Fields", (hooks) => { }); // Opening the modal - await clickEdit(target); await click(target.querySelectorAll(".o_data_row td")[1]); await click(target, ".o_external_button"); assert.containsOnce(target, ".modal"); @@ -3940,8 +3915,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await click(target, ".o_form_button_edit"); - await click(target, ".o_field_many2one input"); assert.containsOnce(target, ".o_field_many2one .dropdown-menu"); @@ -4001,8 +3974,6 @@ QUnit.module("Fields", (hooks) => { arch: '
', }); - await clickEdit(target); - await selectDropdownItem(target, "trululu", "Search More..."); const modal = target.querySelector(".modal"); await toggleGroupByMenu(modal); @@ -4017,7 +3988,7 @@ QUnit.module("Fields", (hooks) => { QUnit.test("focus when closing many2one modal in many2one modal", async function (assert) { serverData.views = { - "partner,false,form": '
', + "partner,false,form": '
', }; await makeView({ @@ -4025,7 +3996,7 @@ QUnit.module("Fields", (hooks) => { serverData, resModel: "partner", resId: 2, - arch: '
', + arch: '
', mockRPC(route, { method }) { if (method === "get_formview_id") { return Promise.resolve(false); @@ -4034,7 +4005,6 @@ QUnit.module("Fields", (hooks) => { }); // Open many2one modal - await clickEdit(target); await click(target, ".o_external_button"); const originalModal = target.querySelector(".modal"); @@ -4102,8 +4072,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await clickEdit(target); - await selectDropdownItem(target, "trululu", "Search More..."); const modal = target.querySelector(".modal"); diff --git a/addons/web/static/tests/views/fields/monetary_field_tests.js b/addons/web/static/tests/views/fields/monetary_field_tests.js index 5504a8d8217..2c56014771f 100644 --- a/addons/web/static/tests/views/fields/monetary_field_tests.js +++ b/addons/web/static/tests/views/fields/monetary_field_tests.js @@ -4,7 +4,6 @@ import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; import { addRow, click, - clickEdit, clickSave, editInput, getFixture, @@ -108,14 +107,6 @@ QUnit.module("Fields", (hooks) => { `, }); - assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "$\u00a09.10", - "The value should be displayed properly." - ); - - await clickEdit(target); - assert.containsOnce( target, ".o_field_monetary > div.text-nowrap", @@ -141,8 +132,8 @@ QUnit.module("Fields", (hooks) => { await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "$\u00a0108.25", + target.querySelector(".o_field_widget input").value, + "108.25", "The new value should be rounded properly." ); }); @@ -169,13 +160,6 @@ QUnit.module("Fields", (hooks) => { `, }); - assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "$\u00a09.10", - "The value should be displayed properly." - ); - - await clickEdit(target); assert.strictEqual( target.querySelector(".o_field_widget input").value, "9.10", @@ -196,8 +180,8 @@ QUnit.module("Fields", (hooks) => { await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "$\u00a0108.25", + target.querySelector(".o_field_widget input").value, + "108.25", "The new value should be rounded properly." ); }); @@ -225,12 +209,11 @@ QUnit.module("Fields", (hooks) => { }); // Test computation and rounding - await clickEdit(target); await editInput(target, ".o_field_monetary input", "=100/3"); await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "$\u00a033.33", + target.querySelector(".o_field_widget input").value, + "33.33", "The new value should be calculated and rounded properly." ); }); @@ -258,12 +241,11 @@ QUnit.module("Fields", (hooks) => { }); // Test computation and rounding - await clickEdit(target); await editInput(target, ".o_field_monetary input", "=100/3"); await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "$\u00a033.33", + target.querySelector(".o_field_widget input").value, + "33.33", "The new value should be calculated and rounded properly." ); }); @@ -290,14 +272,6 @@ QUnit.module("Fields", (hooks) => { `, }); - // Non-breaking space between the currency and the amount - assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "0.00\u00a0€", - "The value should be displayed properly." - ); - - await clickEdit(target); assert.strictEqual( target.querySelector(".o_field_widget input").value, "0.00", @@ -317,10 +291,9 @@ QUnit.module("Fields", (hooks) => { ); await clickSave(target); - // Non-breaking space between the currency and the amount assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "108.25\u00a0€", + target.querySelector(".o_field_widget input").value, + "108.25", "The new value should be rounded properly." ); }); @@ -347,14 +320,6 @@ QUnit.module("Fields", (hooks) => { `, }); - // Non-breaking space between the currency and the amount - assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "0.00\u00a0€", - "The value should be displayed properly." - ); - - await clickEdit(target); assert.strictEqual( target.querySelector(".o_field_widget input").value, "0.00", @@ -374,10 +339,9 @@ QUnit.module("Fields", (hooks) => { ); await clickSave(target); - // Non-breaking space between the currency and the amount assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "108.25\u00a0€", + target.querySelector(".o_field_widget input").value, + "108.25", "The new value should be rounded properly." ); }); @@ -417,14 +381,6 @@ QUnit.module("Fields", (hooks) => { `, }); - // Non-breaking space between the currency and the amount - assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "99.1234\u00a0Bs.F", - "The value should be displayed properly." - ); - - await clickEdit(target); assert.strictEqual( target.querySelector(".o_field_widget input").value, "99.1234", @@ -444,10 +400,9 @@ QUnit.module("Fields", (hooks) => { ); await clickSave(target); - // Non-breaking space between the currency and the amount assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "99.1111\u00a0Bs.F", + target.querySelector(".o_field_widget input").value, + "99.1111", "The new value should be rounded properly." ); }); @@ -487,14 +442,6 @@ QUnit.module("Fields", (hooks) => { `, }); - // Non-breaking space between the currency and the amount - assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "99.1234\u00a0Bs.F", - "The value should be displayed properly." - ); - - await clickEdit(target); assert.strictEqual( target.querySelector(".o_field_widget input").value, "99.1234", @@ -514,10 +461,9 @@ QUnit.module("Fields", (hooks) => { ); await clickSave(target); - // Non-breaking space between the currency and the amount assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "99.1111\u00a0Bs.F", + target.querySelector(".o_field_widget input").value, + "99.1111", "The new value should be rounded properly." ); }); @@ -734,14 +680,6 @@ QUnit.module("Fields", (hooks) => { `, }); - assert.strictEqual( - target.querySelector(".o_field_monetary").textContent, - "$\u00a04.20", - "readonly value should contain the currency" - ); - - await clickEdit(target); - // replace bottom with new helpers when they exist await click(target, ".o_field_many2one_selection input"); const euroM2OListItem = Array.from( @@ -757,10 +695,9 @@ QUnit.module("Fields", (hooks) => { ); await clickSave(target); - assert.strictEqual( - target.querySelector(".o_field_monetary").textContent, - "4.20\u00a0€", + target.querySelector(".o_field_monetary input").value, + "4.20", "The new value should still be correct." ); }); @@ -787,14 +724,6 @@ QUnit.module("Fields", (hooks) => { `, }); - assert.strictEqual( - target.querySelector(".o_field_monetary").textContent, - "$\u00a04.20", - "readonly value should contain the currency" - ); - - await clickEdit(target); - // replace bottom with new helpers when they exist await click(target, ".o_field_many2one_selection input"); const euroM2OListItem = Array.from( @@ -810,10 +739,9 @@ QUnit.module("Fields", (hooks) => { ); await clickSave(target); - assert.strictEqual( - target.querySelector(".o_field_monetary").textContent, - "4.20\u00a0€", + target.querySelector(".o_field_monetary input").value, + "4.20", "The new value should still be correct." ); }); @@ -831,7 +759,7 @@ QUnit.module("Fields", (hooks) => { type: "form", resModel: "partner", arch: ` -
+ @@ -1008,7 +936,7 @@ QUnit.module("Fields", (hooks) => { type: "form", resModel: "partner", arch: ` - + @@ -1059,14 +987,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - // Non-breaking space between the currency and the amount - assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "$\u00a0-8.9", - "The value should be displayed properly." - ); - - await click(target.querySelector(".o_form_button_edit")); assert.strictEqual( target.querySelector(".o_field_widget[name=float_field] input").value, "-8.9", @@ -1086,11 +1006,10 @@ QUnit.module("Fields", (hooks) => { "The value should should be formatted on blur." ); - await click(target.querySelector(".o_form_button_save")); - // Non-breaking space between the currency and the amount + await clickSave(target); assert.strictEqual( - target.querySelector(".o_field_widget").textContent, - "$\u00a0109.2", + target.querySelector(".o_field_widget input").value, + "109.2", "The new value should be rounded properly." ); }); @@ -1110,8 +1029,6 @@ QUnit.module("Fields", (hooks) => { `, }); - await clickEdit(target); - // Non-breaking space between the currency and the amount assert.strictEqual( target.querySelector(".o_field_widget[name=float_field] input").value, @@ -1154,10 +1071,5 @@ QUnit.module("Fields", (hooks) => { assert.containsOnce(target, ".o_form_editable"); assert.strictEqual(target.querySelector("[name=monetary_field] input").value, "0.00"); - - await clickSave(target); - - assert.containsOnce(target, ".o_form_readonly"); - assert.strictEqual(target.querySelector("[name=monetary_field] span").innerText, "0.00"); }); }); diff --git a/addons/web/static/tests/views/fields/numeric_fields_tests.js b/addons/web/static/tests/views/fields/numeric_fields_tests.js index b67fd369a82..a64fadc872c 100644 --- a/addons/web/static/tests/views/fields/numeric_fields_tests.js +++ b/addons/web/static/tests/views/fields/numeric_fields_tests.js @@ -105,9 +105,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - // Record edit mode - await click(target.querySelector(".o_form_button_edit")); - // Get all inputs const floatFactorField = target.querySelector(".o_field_float_factor input"); const floatInput = target.querySelector(".o_field_float input"); diff --git a/addons/web/static/tests/views/fields/one2many_field_tests.js b/addons/web/static/tests/views/fields/one2many_field_tests.js index dc3bdc57c85..3b89e05dd1e 100644 --- a/addons/web/static/tests/views/fields/one2many_field_tests.js +++ b/addons/web/static/tests/views/fields/one2many_field_tests.js @@ -6,7 +6,6 @@ import { click, clickCreate, clickDiscard, - clickEdit, clickSave, clickM2OHighlightedItem, clickOpenedDropdownItem, @@ -308,7 +307,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await click(target, ".o_form_button_edit"); await addRow(target, ".o_field_x2many_list"); @@ -429,7 +427,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await clickEdit(target); await addRow(target); const targetInput = target.querySelector(".o_selected_row [name=foo] input"); @@ -492,15 +489,14 @@ QUnit.module("Fields", (hooks) => { }); assert.verifySteps(["get_views", "read", "read"]); - assert.containsNone(target, "td.o_list_record_selector"); - assert.containsNone(target, ".o_field_x2many_list_row_add"); - assert.containsNone(target, "td.o_list_record_remove", 1); - - await clickEdit(target); + // assert.containsNone(target, "td.o_list_record_selector"); + // assert.containsNone(target, ".o_field_x2many_list_row_add"); + // assert.containsNone(target, "td.o_list_record_remove"); + // await clickEdit(target); assert.containsOnce(target, ".o_field_x2many_list_row_add"); assert.hasAttrValue(target.querySelector(".o_field_x2many_list_row_add"), "colspan", "2"); - assert.containsOnce(target, "td.o_list_record_remove", 1); + assert.containsOnce(target, "td.o_list_record_remove"); }); QUnit.test("transferring class attributes in one2many sub fields", async function (assert) { @@ -520,9 +516,6 @@ QUnit.module("Fields", (hooks) => { }); assert.containsOnce(target, "td.hey"); - await clickEdit(target); - assert.containsOnce(target, "td.hey"); - await click(target.querySelector("td.o_data_cell")); assert.containsOnce(target, 'td.hey div[name="turtle_foo"] input'); // WOWL to check! hey on input? }); @@ -733,13 +726,6 @@ QUnit.module("Fields", (hooks) => { ["yop", "blip", "kawa"] ); - await clickEdit(target); - - assert.deepEqual( - [...target.querySelectorAll(".o_data_cell.o_list_char")].map((el) => el.innerText), - ["yop", "blip", "kawa"] - ); - // Drag and drop the second line in first position await dragAndDrop("tbody tr:nth-child(2) .o_handle_cell", "tbody tr", "top"); @@ -819,7 +805,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await click(target.querySelectorAll(".o_data_cell")[1]); await editInput(target, ".o_selected_row .o_field_widget[name=turtle_foo] input", "hop"); await clickSave(target); @@ -899,7 +884,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await click(target.querySelectorAll(".o_data_cell")[1]); await editInput( target, @@ -984,7 +968,6 @@ QUnit.module("Fields", (hooks) => { ["second record"] ); - await clickEdit(target); await click(target.querySelectorAll(".o_data_cell")[1]); await editInput(target, ".o_selected_row [name=turtle_foo] input", "hop"); await clickSave(target); @@ -1030,8 +1013,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); - assert.deepEqual(getNodesTextContent(target.querySelectorAll(".o_data_cell.o_list_char")), [ "yop", "blip", @@ -1092,8 +1073,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); - assert.deepEqual( getNodesTextContent(target.querySelectorAll(".o_data_cell.o_list_char")), ["yop", "blip", "kawa"] @@ -1156,8 +1135,6 @@ QUnit.module("Fields", (hooks) => { ["yop", "blip", "kawa"] ); - await clickEdit(target); - await click(target.querySelector(".o_data_cell.o_list_char")); await editInput(target, '.o_list_renderer div[name="turtle_foo"] input', "blurp"); @@ -1242,13 +1219,12 @@ QUnit.module("Fields", (hooks) => { ).join(""); }; - await clickEdit(target); assert.strictEqual(getTurtleFooValues(), "#20#21#22#23#24#25#26#27#28#29"); await click(target.querySelector(".o_data_cell.o_list_char")); await editInput(target, "div[name=turtle_foo] input", "blurp"); // click outside of the one2many to unselect the row - await click(target, ".o_cp_bottom_left"); + await click(target, ".o_form_view"); assert.strictEqual(getTurtleFooValues(), "blurp#21#22#23#24#25#26#27#28#29"); // the domain fail if the widget does not use the already loaded data. @@ -1256,7 +1232,6 @@ QUnit.module("Fields", (hooks) => { assert.containsNone(target, ".modal"); assert.strictEqual(getTurtleFooValues(), "#20#21#22#23#24#25#26#27#28#29"); - await clickEdit(target); // Drag and drop the third line in second position await dragAndDrop("tbody tr:nth-child(3) .o_handle_cell", "tbody tr:nth-child(2)"); assert.strictEqual(getTurtleFooValues(), "#20#30#31#32#33#34#35#36#37#38"); @@ -1265,7 +1240,7 @@ QUnit.module("Fields", (hooks) => { await dragAndDrop("tbody tr:nth-child(3) .o_handle_cell", "tbody tr:nth-child(2)"); assert.strictEqual(getTurtleFooValues(), "#20#39#40#41#42#43#44#45#46#47"); - await click(target, ".o_cp_bottom_left"); + await click(target, ".o_form_view"); assert.strictEqual(getTurtleFooValues(), "#20#39#40#41#42#43#44#45#46#47"); await clickDiscard(target); @@ -1313,7 +1288,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); await click(target.querySelector(".o_field_widget[name=turtles] .o_pager_next")); await click( @@ -1449,7 +1423,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); await click(target.querySelector(".o_field_widget[name=turtles] .o_pager_next")); await click( @@ -1563,7 +1536,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); assert.containsOnce(target, ".o_data_row"); // change the value of foo to trigger the onchange @@ -1619,7 +1591,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); assert.containsOnce( target, ".o_data_row", @@ -1695,7 +1666,6 @@ QUnit.module("Fields", (hooks) => { }, resId: 1, }); - await clickEdit(target); assert.containsOnce(target, ".o_data_row"); assert.deepEqual( @@ -2005,8 +1975,6 @@ QUnit.module("Fields", (hooks) => { const formHandle = Object.keys(model.localData).find((k) => /partner/.test(k)); - await clickEdit(target); - assert.deepEqual( Object.values(model.get(formHandle).data.turtles.data).map((r) => { return r.data; @@ -2086,13 +2054,6 @@ QUnit.module("Fields", (hooks) => { "yop", ]); - await clickEdit(target); - assert.deepEqual(getNodesTextContent(target.querySelectorAll(".o_data_cell.o_list_char")), [ - "My little Foo Value", - "blip", - "yop", - ]); - assert.verifySteps([]); // Drag and drop the second line in first position @@ -2363,7 +2324,6 @@ QUnit.module("Fields", (hooks) => { // add a record on page one checkRead = true; - await clickEdit(target); await click(target.querySelector(".o-kanban-button-new")); await editInput(target, ".modal input", "new record"); @@ -2394,7 +2354,6 @@ QUnit.module("Fields", (hooks) => { // delete a record on page one checkRead = true; - await clickEdit(target); assert.strictEqual( target.querySelector(".o_kanban_record:not(.o_kanban_ghost)").innerText, "relational record 10" @@ -2423,7 +2382,6 @@ QUnit.module("Fields", (hooks) => { await clickSave(target); // add and delete records in both pages - await clickEdit(target); checkRead = true; readIDs = undefined; // add and delete a record in page 1 @@ -2500,7 +2458,7 @@ QUnit.module("Fields", (hooks) => { resModel: "partner", serverData, arch: ` -
+ @@ -2557,8 +2515,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); - assert.strictEqual(target.querySelector(".o_kanban_record ").innerText, "donatello"); await click(target.querySelector(".o_kanban_record")); @@ -2633,7 +2589,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); await addRow(target); await editInput(target, 'div[name="turtle_int"] input', "5"); await click(target.querySelector(".modal-footer button.btn-primary")); @@ -2721,7 +2676,6 @@ QUnit.module("Fields", (hooks) => { "relational record 1" ); - await clickEdit(target); await click(target.querySelector(".o_field_one2many tbody td")); assert.hasClass( target.querySelector(".o_field_one2many tbody .o_data_row"), @@ -2754,7 +2708,6 @@ QUnit.module("Fields", (hooks) => { ); // edit again and save - await clickEdit(target); await click(target.querySelector(".o_field_one2many tbody td")); await editInput(target, ".o_field_one2many tbody td input", "new value"); await click(target.querySelector(".o_form_view")); @@ -2783,9 +2736,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); assert.containsNone(target, ".o_field_x2many_list_row_add"); - - await clickEdit(target); - assert.containsNone(target, ".o_field_x2many_list_row_add"); }); QUnit.test("one2many list: conditional create/delete actions", async function (assert) { @@ -2806,7 +2756,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); // bar is true -> create and delete action are available assert.containsOnce(target, ".o_field_x2many_list_row_add"); assert.containsN(target, "td.o_list_record_remove button", 2); @@ -2859,7 +2808,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await clickEdit(target); assert.containsN(target, "td.o_list_record_remove button", 3); await click(target.querySelector("td.o_list_record_remove button")); @@ -2905,7 +2853,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await clickEdit(target); assert.containsN(target, "td.o_list_record_remove button", 3); await click(target.querySelector("td.o_list_record_remove button")); @@ -2920,7 +2867,7 @@ QUnit.module("Fields", (hooks) => { }); QUnit.test("one2many kanban: edition", async function (assert) { - assert.expect(22); + assert.expect(20); serverData.models.partner.records[0].p = [2]; await makeView({ @@ -2969,11 +2916,6 @@ QUnit.module("Fields", (hooks) => { }, }); - assert.containsNone(target, ".delete_icon"); - assert.containsNone(target, ".o_field_one2many .o-kanban-button-new"); - - await clickEdit(target); - assert.containsOnce(target, ".o_kanban_record:not(.o_kanban_ghost)"); assert.strictEqual( target.querySelector(".o_kanban_record span").textContent, @@ -3100,7 +3042,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); assert.deepEqual( [ ...target.querySelectorAll( @@ -3138,9 +3079,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - assert.containsNone(target, ".o-kanban-button-new"); - - await clickEdit(target); assert.containsNone(target, ".o-kanban-button-new"); assert.containsOnce(target, ".o_field_x2many_kanban .delete_icon"); @@ -3175,7 +3113,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); // bar is initially true -> create and delete actions are available assert.containsOnce(target, ".o-kanban-button-new", '"Add" button should be available'); @@ -3223,7 +3160,6 @@ QUnit.module("Fields", (hooks) => { }); // add a record, add value to turtle_foo then click in form view to confirm it - await clickEdit(target); await addRow(target); await editInput(target, 'div[name="turtle_foo"] input', "nora"); @@ -3237,7 +3173,7 @@ QUnit.module("Fields", (hooks) => { }); QUnit.test("one2many list (non editable): edition", async function (assert) { - assert.expect(12); + assert.expect(10); let nbWrite = 0; serverData.models.partner.records[0].p = [2, 4]; @@ -3271,11 +3207,6 @@ QUnit.module("Fields", (hooks) => { }, }); - assert.containsNone(target, ".o_list_record_remove"); - assert.containsNone(target, ".o_field_x2many_list_row_add"); - - await clickEdit(target); - assert.containsN(target, "td.o_list_number", 2); assert.strictEqual( target.querySelector(".o_list_renderer tbody td").textContent, @@ -3341,7 +3272,6 @@ QUnit.module("Fields", (hooks) => { }); // edit mode, then click on Add an item and enter a value - await clickEdit(target); await addRow(target); await editInput(target, ".o_selected_row > td input", "kartoffel"); assert.strictEqual(target.querySelector("td .o_field_char input").value, "kartoffel"); @@ -3383,7 +3313,6 @@ QUnit.module("Fields", (hooks) => { // edit mode, then click on Add an item, enter value in turtle_foo and Add an item again assert.containsOnce(target, "tr.o_data_row"); - await clickEdit(target); await addRow(target); await editInput(target, 'div[name="turtle_foo"] input', "nora"); await addRow(target); @@ -3429,7 +3358,6 @@ QUnit.module("Fields", (hooks) => { // edit mode, then click on Add an item assert.containsNone(target, "tr.o_data_row"); - await clickEdit(target); await addRow(target); assert.strictEqual(target.querySelector(".o_data_row textarea").value, ""); @@ -3460,7 +3388,6 @@ QUnit.module("Fields", (hooks) => { // edit mode, then click on Add an item, enter value in turtle_foo and Add an item again assert.containsOnce(target, "tr.o_data_row"); assert.strictEqual(target.querySelector(".o_data_cell").innerText, "blip"); - await clickEdit(target); await addRow(target); await editInput(target, ".o_field_widget[name=turtle_foo] input", "aaa"); assert.containsN(target, "tr.o_data_row", 2); @@ -3497,7 +3424,6 @@ QUnit.module("Fields", (hooks) => { // edit mode, then click on Add an item, then click elsewhere assert.containsNone(target, "tr.o_data_row"); - await clickEdit(target); await addRow(target); await click(target); assert.containsNone(target, "tr.o_data_row"); @@ -3528,7 +3454,6 @@ QUnit.module("Fields", (hooks) => { }); // add a record, to reach the page size limit - await clickEdit(target); await addRow(target); // the record currently being added should not count in the pager assert.containsNone(target, ".o_field_widget[name=turtles] .o_pager"); @@ -3567,7 +3492,6 @@ QUnit.module("Fields", (hooks) => { }); // add a record, then discard - await clickEdit(target); await addRow(target); await clickDiscard(target); @@ -3601,7 +3525,6 @@ QUnit.module("Fields", (hooks) => { }); // add a (empty) record - await clickEdit(target); await addRow(target); // go on next page. The new record is not valid and should be discarded @@ -3633,7 +3556,6 @@ QUnit.module("Fields", (hooks) => { }); // add a record with a dirty state, but not valid - await clickEdit(target); await addRow(target); await editInput(target, '.o_field_widget[name="turtle_int"] input', 4321); @@ -3708,7 +3630,6 @@ QUnit.module("Fields", (hooks) => { }); // add 4 records (to have more records than the limit) - await clickEdit(target); await addRow(target); await editInput(target, '.o_field_widget[name="turtle_foo"] input', "nora"); await addRow(target); @@ -3750,7 +3671,6 @@ QUnit.module("Fields", (hooks) => { // edit mode, then click on Add an item, then click elsewhere assert.containsNone(target, "tr.o_data_row"); - await clickEdit(target); await addRow(target); assert.containsOnce(target, "tr.o_data_row"); @@ -3793,7 +3713,6 @@ QUnit.module("Fields", (hooks) => { }); // edit mode, then click on Add an item, then press enter - await clickEdit(target); await addRow(target); triggerHotkey("Enter"); await nextTick(); @@ -3817,7 +3736,6 @@ QUnit.module("Fields", (hooks) => { resId: 2, }); - await clickEdit(target); await addRow(target); assert.containsOnce(target, ".o_data_row"); assert.hasClass(target.querySelectorAll(".o_data_row")[0], "o_selected_row"); @@ -3860,7 +3778,6 @@ QUnit.module("Fields", (hooks) => { resId: 2, }); - await clickEdit(target); await addRow(target); assert.strictEqual( document.activeElement, @@ -3910,7 +3827,6 @@ QUnit.module("Fields", (hooks) => { // edit mode, then click on Add an item assert.containsNone(target, "tr.o_data_row"); - await clickEdit(target); await addRow(target); // input some text in required turtle_foo field @@ -3954,7 +3870,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await addRow(target); assert.containsOnce(target, "tr.o_data_row"); @@ -3986,7 +3901,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await addRow(target); assert.containsOnce(target, "tr.o_data_row"); @@ -4024,8 +3938,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); - await addRow(target); await addRow(target, ".modal"); @@ -4065,7 +3977,6 @@ QUnit.module("Fields", (hooks) => { }); assert.verifySteps(["get_views", "read", "read"]); - await clickEdit(target); await click(target.querySelector(".o_data_cell")); await editInput(target, ".o_field_widget[name=product_id] input", ""); assert.verifySteps([], "no onchange should be done as line is invalid"); @@ -4109,7 +4020,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await click(target.querySelector(".o_field_one2many tbody td")); await editInput( target.querySelector(".o_field_one2many tbody td input"), @@ -4205,7 +4115,6 @@ QUnit.module("Fields", (hooks) => { assert.step(args.method); }, }); - await clickEdit(target); const td = target.querySelector("td"); assert.strictEqual(td.textContent, "9"); await click(td); @@ -4236,7 +4145,6 @@ QUnit.module("Fields", (hooks) => { assert.step(args.method); }, }); - await clickEdit(target); const td = target.querySelector("td"); assert.strictEqual(td.textContent, "01/25/2017"); @@ -4293,7 +4201,6 @@ QUnit.module("Fields", (hooks) => { }, resId: 1, }); - await clickEdit(target); assert.containsOnce(target, ".o_data_row"); // empty o2m by triggering the onchange @@ -4385,7 +4292,6 @@ QUnit.module("Fields", (hooks) => { }, resId: 1, }); - await clickEdit(target); assert.containsOnce(target, ".o_data_row"); await click(target.querySelector(".o_field_one2many td")); await editInput(target, ".o_field_widget[name=display_name] input", "blurp"); @@ -4481,7 +4387,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); assert.containsNone(target, ".o_data_row"); await addRow(target); @@ -4536,7 +4441,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); assert.containsOnce(target, ".o_form_view .o_field_x2many_list_row_add "); assert.containsNone(target, ".o_form_view input"); @@ -4566,7 +4470,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); assert.deepEqual( [...target.querySelectorAll(".o_data_cell")].map((el) => el.textContent), ["first record", "second record", "aaa"] @@ -4601,7 +4504,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); // switch the first row in edition await click(target.querySelector(".o_data_cell")); @@ -4688,7 +4590,6 @@ QUnit.module("Fields", (hooks) => { assert.containsOnce(target, ".o_data_cell[data-tooltip='xphone']"); assert.containsNone(target, ".o_data_cell[data-tooltip='xpad']"); - await clickEdit(target); await addRow(target); checkOnchange = true; @@ -4741,7 +4642,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await clickEdit(target); await addRow(target); // write in the many2one field, value = 37 (xphone) @@ -4830,7 +4730,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); // open a modal await click(target.querySelector("tr.o_data_row td[data-tooltip='xphone']")); @@ -4870,7 +4769,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await click(target, ".o_field_widget[name=product_id] input"); } ); @@ -4908,7 +4806,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await click(target.querySelector("tr.o_data_row td[data-tooltip='xphone']")); // trigger a name search @@ -4949,7 +4846,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await addRow(target); }); @@ -4992,7 +4888,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await addRow(target); await editInput(target, '[name="turtle_foo"] input', "hammer"); await addRow(target); @@ -5015,7 +4910,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); await addRow(target); assert.containsOnce( target, @@ -5067,7 +4961,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await addRow(target); } ); @@ -5103,7 +4996,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await addRow(target); assert.containsOnce(target, ".modal"); } @@ -5167,7 +5059,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await addRow(target); assert.strictEqual( @@ -5179,8 +5070,7 @@ QUnit.module("Fields", (hooks) => { await click($(".modal .o_data_row:first .o_list_record_selector input")[0]); await nextTick(); // additional render due to the change of selection (done in owl, not pure js) await click($(".modal .o_select_button")[0]); - await click($(".o_form_button_save")[0]); - await clickEdit(target); + await clickSave(target); await addRow(target); assert.strictEqual( @@ -5206,7 +5096,7 @@ QUnit.module("Fields", (hooks) => { "should display the record values in one2many list" ); - await click($(".o_form_button_save")[0]); + await clickSave(target); }); QUnit.test("one2many with many2many widget: edition", async function (assert) { @@ -5273,7 +5163,6 @@ QUnit.module("Fields", (hooks) => { }, }); //await new Promise(() => {}) - await clickEdit(target); await click($(target).find(".o_data_cell:first")[0]); assert.strictEqual( $(".modal .modal-title").first().text().trim(), @@ -5288,10 +5177,9 @@ QUnit.module("Fields", (hooks) => { await clickM2OHighlightedItem(target, "product_id"); await click($(".modal-footer button:first")[0]); - await click($(".o_form_button_save")[0]); + await clickSave(target); // add a one2many record - await clickEdit(target); await addRow(target); await click($(".modal .o_data_row:first .o_list_record_selector input")[0]); await nextTick(); // wait for re-rendering because of the change of selection @@ -5303,7 +5191,7 @@ QUnit.module("Fields", (hooks) => { await clickM2OHighlightedItem(target, "product_id"); await click($(".modal .modal-footer button:first")[0]); - await click($(".o_form_button_save")[0]); + await clickSave(target); }); QUnit.test("new record, the context is properly evaluated and sent", async function (assert) { @@ -5369,7 +5257,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); await addRow(target); }); @@ -5409,7 +5296,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await clickEdit(target); assert.containsOnce(target, ".o_data_row"); await click(target.querySelector(".o_data_row .o_data_cell")); @@ -5539,7 +5425,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); await addRow(target); await click(target.querySelector(".modal-footer button.btn-primary")); @@ -5733,8 +5618,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); - await addRow(target, ".o_field_one2many"); assert.containsOnce(target, ".modal"); await click(target.querySelector(".modal-footer button")); @@ -5790,7 +5673,7 @@ QUnit.module("Fields", (hooks) => { }); QUnit.test("many2one and many2many in one2many", async function (assert) { - assert.expect(13); + assert.expect(12); serverData.models.turtle.records[1].product_id = 37; serverData.models.partner.records[0].turtles = [2, 3]; @@ -5862,13 +5745,9 @@ QUnit.module("Fields", (hooks) => { "m2m values should have been correctly fetched" ); - await click(target.querySelector(".o_data_row td")); - - assert.strictEqual(target.querySelector(".modal .o_field_widget").innerText, "xphone"); - - await click(target.querySelector(".modal-footer button")); - - await clickEdit(target); + // await click(target.querySelector(".o_data_row td")); + // assert.strictEqual(target.querySelector(".modal .o_field_widget").innerText, "xphone"); + // await click(target.querySelector(".modal-footer button")); assert.containsOnce( target, @@ -5946,7 +5825,6 @@ QUnit.module("Fields", (hooks) => { assert.step(args.method); }, }); - await clickEdit(target); assert.containsN(target, ".o_data_row", 2); await click(target.querySelector(".o_list_record_remove")); @@ -6185,7 +6063,7 @@ QUnit.module("Fields", (hooks) => { resModel: "partner", serverData, arch: ` -
+ @@ -6249,8 +6127,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); - await click(target.querySelector(".o_data_row td")); // edit first record await click(target.querySelector('div[name="partner_ids"] input')); @@ -6282,7 +6158,7 @@ QUnit.module("Fields", (hooks) => { - + `, @@ -6301,8 +6177,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); - // edit the first partner in the one2many partner form view await click(target.querySelector(".o_data_row td.o_data_cell")); // open form view for many2one @@ -6530,7 +6404,7 @@ QUnit.module("Fields", (hooks) => { resModel: "partner", serverData, arch: ` -
+ @@ -6602,8 +6476,7 @@ QUnit.module("Fields", (hooks) => { "should not have kanban records yet" ); - // // switch to edit mode and create a new kanban record - await clickEdit(target); + // create a new kanban record await click(target, ".o_field_widget .o-kanban-button-new"); // save & close the modal @@ -6761,9 +6634,6 @@ QUnit.module("Fields", (hooks) => { await click(target, btn1Warn); assert.verifySteps(["button_warn_partner_4"]); - // switch to edit mode - await clickEdit(target); - // click on existing buttons await click(target, btn1Disabled); assert.verifySteps(["button_disabled_partner_4"]); @@ -6813,8 +6683,7 @@ QUnit.module("Fields", (hooks) => { ]); // save the form - await clickSave(target); - assert.verifySteps([]); // the write has already been done + assert.containsOnce(target, ".o_form_saved"); // click all buttons await click(target, btn1Disabled); @@ -6852,7 +6721,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); await click(target.querySelector(".o_data_row td")); const turtleFooInput = target.querySelector('[name="turtle_foo"] input'); @@ -6891,8 +6759,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await clickEdit(target); - assert.containsOnce(target, ".o_data_row", "should start with one data row"); await addRow(target); @@ -6939,7 +6805,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await clickEdit(target); assert.containsOnce(target, ".o_data_row", "should start with one data row"); @@ -6980,15 +6845,12 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); await addRow(target); assert.containsOnce(target, ".modal"); assert.containsNone(target, ".modal .modal-footer .o_btn_remove"); // Discard a modal await click(target.querySelector(".modal-footer .btn-secondary")); - - await clickDiscard(target); }); QUnit.test('x2many fields use their "mode" attribute', async function (assert) { @@ -7054,7 +6916,6 @@ QUnit.module("Fields", (hooks) => { }, resId: 1, }); - await clickEdit(target); assert.strictEqual( target.querySelector('.o_field_widget[name="int_field"] input').value, "0" @@ -7121,7 +6982,6 @@ QUnit.module("Fields", (hooks) => { }, resId: 1, }); - await clickEdit(target); assert.strictEqual( $(target).find('.o_field_widget[name="int_field"] input').val(), @@ -7185,7 +7045,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); assert.strictEqual( target.querySelector('.o_field_widget[name="int_field"] input').value, "10" @@ -7234,7 +7093,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); assert.strictEqual( target.querySelector('.o_field_widget[name="int_field"] input').value, "10" @@ -7432,8 +7290,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await clickEdit(target); - patchWithCleanup(form.env.services.notification, { add: (message, params) => { assert.step(params.type); @@ -7512,8 +7368,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, context: { active_field: 2 }, }); - await clickEdit(target); - await click(target.querySelector(".o_data_cell")); await editInput(target, ".o_field_widget[name=display_name] input", "abc"); await clickSave(target); @@ -7539,8 +7393,6 @@ QUnit.module("Fields", (hooks) => { assert.step(args.method); }, }); - await clickEdit(target); - await editInput(target, '[name="foo"] input', "abcd"); assert.verifySteps(["get_views", "read", "onchange"]); }); @@ -7598,7 +7450,7 @@ QUnit.module("Fields", (hooks) => { ); QUnit.test("multi level of nested x2manys, onchange and rawChanges", async function (assert) { - assert.expect(8); + assert.expect(7); serverData.models.partner.records[0].p = [1]; serverData.models.partner.onchanges = { name: function () {}, @@ -7634,14 +7486,7 @@ QUnit.module("Fields", (hooks) => { assert.containsOnce(target, ".o_data_row"); - // open the o2m record in readonly first - await click(target.querySelector(".o_data_row td")); - assert.containsOnce(target, ".modal .o_form_readonly"); - - await clickDiscard(target.querySelector(".modal")); - - // switch to edit mode and open it again - await clickEdit(target); + // open the dialog await click(target.querySelector(".o_data_row td")); assert.containsOnce(target, ".modal .o_form_editable"); assert.containsOnce(target, ".modal .o_data_row"); @@ -7692,8 +7537,6 @@ QUnit.module("Fields", (hooks) => { assert.step(args.method); }, }); - await clickEdit(target); - // triggers an onchange on partner, because the new record is valid await addRow(target); @@ -7784,8 +7627,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - - await clickEdit(target); await addRow(target); assert.containsN(target, "tr.o_data_row", 41); assert.hasClass([...target.querySelectorAll("tr.o_data_row")].pop(), "o_selected_row"); @@ -7819,8 +7660,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - - await clickEdit(target); // add a new record page 1 (this increases the limit to 4) await addRow(target); await editInput(target, '.o_data_row [name="turtle_foo"] input', "rainbow dash"); @@ -7863,8 +7702,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - - await clickEdit(target); await click(target, ".o_field_widget[name=turtles] .o_pager_next"); assert.containsN(target, "tr.o_data_row", 2); @@ -8081,8 +7918,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); - let rows = target.querySelectorAll(".o_data_row"); await click(rows[0].querySelector(".o_data_cell")); assert.containsOnce(target, ".o_data_row.o_selected_row"); @@ -8191,7 +8026,6 @@ QUnit.module("Fields", (hooks) => { }, resId: 1, }); - await clickEdit(target); assert.strictEqual(target.querySelector(".o_data_row .o_data_cell").textContent, "blip"); // click and edit value to 'foo', which will trigger onchange @@ -8418,7 +8252,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await clickEdit(target); await click(target.querySelector(".o_list_record_remove button")); assert.deepEqual( [...target.querySelectorAll(".o_data_row")].map((el) => el.textContent), @@ -8460,7 +8293,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await clickEdit(target); assert.deepEqual( getNodesTextContent(target.querySelectorAll(".o_data_row .o_data_cell.o_list_char")), ["yop", "blip"] @@ -8493,8 +8325,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); - // starting condition assert.deepEqual( [...target.querySelectorAll(".o_data_row")].map((el) => el.textContent), @@ -8538,8 +8368,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); - // starting condition assert.deepEqual( [...target.querySelectorAll(".o_data_row")].map((el) => el.textContent), @@ -8587,8 +8415,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); - // starting condition assert.deepEqual( [...target.querySelectorAll(".o_data_row")].map((el) => el.textContent), @@ -8641,8 +8467,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); - // click add a new line // check turtle_int for new is the current max of the page await addRow(target); @@ -8676,9 +8500,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - - await clickEdit(target); - // click add a new line // check turtle_int for new is the current max of the page +1 await addRow(target); @@ -8806,7 +8627,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await click(target, ".o_form_button_edit"); assert.deepEqual( [...target.querySelectorAll(".o_data_cell.foo")].map((el) => el.textContent), ["blip", "kawa"] @@ -8907,7 +8727,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await click(target, ".o_form_button_edit"); await addRow(target); assert.containsN(target, ".o_data_row", 4); @@ -8956,9 +8775,6 @@ QUnit.module("Fields", (hooks) => { assert.step(args.method); }, }); - - await clickEdit(target); - // swap 2 lines in the one2many await dragAndDrop("tbody tr:nth-child(2) .o_handle_cell", "tbody tr", "top"); @@ -9224,7 +9040,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); assert.deepEqual( [...target.querySelector(".o_field_x2many_list_row_add").children].map( (el) => el.textContent @@ -9305,9 +9120,6 @@ QUnit.module("Fields", (hooks) => { `, }); - - await clickEdit(target); - assert.containsOnce(target, ".o_data_row"); assert.strictEqual(target.querySelector(".o_data_cell").textContent, "second record"); @@ -9390,7 +9202,6 @@ QUnit.module("Fields", (hooks) => { }); // add a turtle on second partner - await clickEdit(target); await click(target.querySelectorAll(".o_data_row")[1].querySelector(".o_data_cell")); await addRow(target.querySelector(".modal")); await editInput(target, ".modal .o_field_widget[name=display_name] input", "michelangelo"); @@ -9568,8 +9379,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); - // add a row, fill it, then trigger the tab shortcut await addRow(target); await editInput(target, "[name=turtle_foo] textarea", "ninja"); @@ -9617,8 +9426,6 @@ QUnit.module("Fields", (hooks) => { } }, }); - await clickEdit(target); - await click(target.querySelector(".o_data_row .o_data_cell")); await editInput(target, "[name='turtle_foo'] input", "Test"); assert.containsOnce(target, ".o_data_row"); @@ -9791,7 +9598,7 @@ QUnit.module("Fields", (hooks) => { await addRow(target); await clickSave(target); - assert.containsOnce(target, ".o_form_readonly"); + assert.containsOnce(target, ".o_form_editable"); assert.strictEqual( target.querySelector(".o_data_row").textContent.trim(), "some foo value" @@ -9833,8 +9640,6 @@ QUnit.module("Fields", (hooks) => { }, }); - await clickEdit(target); - // Add a record in the list await addRow(target); await editInput(target, ".modal div[name=display_name] input", "michelangelo"); @@ -9893,7 +9698,6 @@ QUnit.module("Fields", (hooks) => { "should be 2 columns in the one2many" ); - await clickEdit(target); await selectDropdownItem(target, "product_id", "xphone"); assert.containsOnce( @@ -9934,8 +9738,6 @@ QUnit.module("Fields", (hooks) => { `, resId: 1, }); - await clickEdit(target); - assert.strictEqual( target.querySelector(".o_field_widget[name=product_id] input").value, "" @@ -9975,7 +9777,6 @@ QUnit.module("Fields", (hooks) => { resId: 1, }); - await clickEdit(target); assert.strictEqual( target.querySelector(".o_field_widget[name=product_id] input").value, "" @@ -10083,17 +9884,14 @@ QUnit.module("Fields", (hooks) => { ["yop", "blip", "kawa"] ); - // should not work (form in mode "readonly") - await dragAndDrop(".o_kanban_record:nth-child(1)", ".o_kanban_record:nth-child(3)"); - - assert.deepEqual( - [...target.querySelectorAll(".o_kanban_record:not(.o_kanban_ghost)")].map( - (el) => el.innerText - ), - ["yop", "blip", "kawa"] - ); - - await clickEdit(target); + // // should not work (form in mode "readonly") + // await dragAndDrop(".o_kanban_record:nth-child(1)", ".o_kanban_record:nth-child(3)"); + // assert.deepEqual( + // [...target.querySelectorAll(".o_kanban_record:not(.o_kanban_ghost)")].map( + // (el) => el.innerText + // ), + // ["yop", "blip", "kawa"] + // ); await dragAndDrop(".o_kanban_record:nth-child(1)", ".o_kanban_record:nth-child(3)"); @@ -10133,7 +9931,6 @@ QUnit.module("Fields", (hooks) => { assert.containsOnce(target, ".o_data_row"); // edit first row - await clickEdit(target); await click(target.querySelector(".o_data_row .o_data_cell")); assert.hasClass(target.querySelector(".o_data_row"), "o_selected_row"); target.querySelector(".o_selected_row .o_field_widget[name=turtle_int] input").value = "44"; @@ -10446,40 +10243,6 @@ QUnit.module("Fields", (hooks) => { assert.strictEqual(target.querySelector('th[data-name="date"]').offsetWidth, width); }); - QUnit.test("editable one2many list with oe_read_only button", async function (assert) { - await makeView({ - type: "form", - resModel: "partner", - serverData, - arch: ` -
- - - -