[FIX] website: fix edit menus tour

This commit aims at making the website dialog as well as the edit_menus
tour more stable.

Commit [1] introduced a new dialog API for website.
The component WebsiteDialog handles click asynchronously.

Prior to this commit, the tour could sometimes detect and click on modal
triggers before the actions that the previous trigger was triggering
could complete. This could lead to a modal closing too early either
because a click would done on the wrong modal or the input was completed
before the validation method was called (since the click handlers are
asynchronous).

Here are a few examples of possible failure in the tour :

- The tour clicks on "Add Menu Item", which should open a new modal
- The tour then clicks on OK to make sure the modal does not close.
- The click on OK is done before the New Menu Item modal is open and
  therefore is triggered on the previous modal
- The modal is closed too early

- The tour clicks on OK while the URL field is empty
- Before the validation method is processed the tour inserts a value in
  the input field.
- The validation method doesn't block the OK method which results in the
  dialog being closed
- The tour expects the dialog to be open and crashes

- The tour clicks on OK while the URL field is empty
- Before the validation method is processed the tour inserts a value in
  the input field
- The tour clicks on OK again
- 2 entries are created instead of one.

The last one doesn't crash the tour but is still incorrect.

This commit disables the buttons when they're clicked for the first time
until the handler is processed.

This commit also make the triggers in the tour more specific so that the
tour always clicks on the right modals.

[1]: https://github.com/odoo/odoo/commit/28a78fb4e4e4465aa99fb94f7cac3a21b2188502

runbot-4122

closes odoo/odoo#95839

Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
Arthur Detroux (ard)
2022-07-18 18:41:09 +02:00
parent 8d22dd8ae9
commit 982e3c2671
3 changed files with 30 additions and 16 deletions
@@ -10,21 +10,33 @@ const { xml, useState, Component } = owl;
const NO_OP = () => {};
export class WebsiteDialog extends Component {
async primaryClick() {
if (this.props.primaryClick) {
await this.props.primaryClick();
}
if (this.props.closeOnClick) {
this.props.close();
}
setup() {
this.state = useState({
disabled: false,
});
}
async secondaryClick() {
if (this.props.secondaryClick) {
await this.props.secondaryClick();
}
if (this.props.closeOnClick) {
this.props.close();
/**
* Disables the buttons of the dialog when a click is made.
* If a handler is provided, await for its call.
* If the prop closeOnClick is true, close the dialog.
* Otherwise, restore the button.
*
* @param handler {function|void} The handler to protect.
* @returns {function(): Promise} handler called when a click is made.
*/
protectedClick(handler) {
return async () => {
if (this.state.disabled) {
return;
}
this.state.disabled = true;
if (handler) {
await handler();
}
if (this.props.closeOnClick) {
return this.props.close();
}
this.state.disabled = false;
}
}
@@ -11,10 +11,10 @@
<t t-set-slot="footer">
<t t-if="props.slots and props.slots.footer" t-slot="footer"/>
<t t-else="">
<button class="btn btn-primary" t-on-click="primaryClick">
<button class="btn btn-primary" t-on-click="protectedClick(props.primaryClick)" t-att-disabled="state.disabled">
<t t-esc="props.primaryTitle"/>
</button>
<button t-if="props.showSecondaryButton" class="btn btn-secondary" t-on-click="secondaryClick">
<button t-if="props.showSecondaryButton" class="btn btn-secondary" t-on-click="protectedClick(props.secondaryClick)" t-att-disabled="state.disabled">
<t t-esc="props.secondaryTitle"/>
</button>
</t>
@@ -59,6 +59,7 @@ wTourUtils.registerEditionTour('edit_menus', {
},
{
content: "Confirm the new menu entry without a label",
extra_trigger: '.modal-dialog .o_website_dialog input:eq(0)',
trigger: '.modal-footer .btn-primary',
},
{
@@ -74,6 +75,7 @@ wTourUtils.registerEditionTour('edit_menus', {
{
content: "It didn't save without a url. Fill url input.",
trigger: '.modal-dialog .o_website_dialog input:eq(1)',
extra_trigger: '.modal-dialog .o_website_dialog input.is-invalid',
run: 'text #',
},
{