diff --git a/addons/web_tour/static/src/js/tip.js b/addons/web_tour/static/src/js/tip.js index b08c12dce52..1f7758d6ada 100644 --- a/addons/web_tour/static/src/js/tip.js +++ b/addons/web_tour/static/src/js/tip.js @@ -27,6 +27,8 @@ var Tip = Widget.extend({ * - position [String] tip's position ('top', 'right', 'left' or 'bottom'), default 'right' * - width [int] the width in px of the tip when opened, default 270 * - space [int] space in px between anchor and tip, default 10 + * - hidden [boolean] if true, the tip won't be visible (but the handlers will still be + * bound on the anchor, so that the tip is consumed if the user clicks on it) * - overlay [Object] x and y values for the number of pixels the mouseout detection area * overlaps the opened tip, default {x: 50, y: 50} */ @@ -89,6 +91,7 @@ var Tip = Widget.extend({ this._bind_anchor_events(); this._updatePosition(true); + this.$el.toggleClass('d-none', !!this.info.hidden); this.$el.css("opacity", 1); core.bus.on("resize", this, _.debounce(function () { if (this.tip_opened) { diff --git a/addons/web_tour/static/src/js/tour_manager.js b/addons/web_tour/static/src/js/tour_manager.js index bdcb3f91c7f..aae5c85bf38 100644 --- a/addons/web_tour/static/src/js/tour_manager.js +++ b/addons/web_tour/static/src/js/tour_manager.js @@ -235,12 +235,11 @@ return core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, { const sortedTooltips = Object.keys(this.active_tooltips).sort( (a, b) => this.tours[a].sequence - this.tours[b].sequence ); + let visibleTip = false; for (const tourName of sortedTooltips) { var tip = this.active_tooltips[tourName]; - var activated = this._check_for_tooltip(tip, tourName); - if (activated) { - break; - } + tip.hidden = visibleTip; + visibleTip = this._check_for_tooltip(tip, tourName) || visibleTip; } } }, diff --git a/addons/web_tour/static/tests/tour_manager_tests.js b/addons/web_tour/static/tests/tour_manager_tests.js index 14802f9086f..0b8f7e0679d 100644 --- a/addons/web_tour/static/tests/tour_manager_tests.js +++ b/addons/web_tour/static/tests/tour_manager_tests.js @@ -71,12 +71,48 @@ odoo.define('web_tour.tour_manager_tests', async function (require) { debug: true, }); - assert.containsOnce(document.body, '.o_tooltip'); - const tooltip = document.querySelector('.o_tooltip_content'); - assert.strictEqual(tooltip.innerHTML.trim(), "Oui", + assert.containsOnce(document.body, '.o_tooltip:visible'); + assert.strictEqual($('.o_tooltip_content:visible').text(), "Oui", "content should be that of the third tour"); tourManager.destroy(); }); + + QUnit.test("Click on invisible tip consumes it", async function (assert) { + assert.expect(5); + + const tourManager = await createTourManager({ + template: ` + + + `, + tours: [{ + name: "Tour 1", + options: { rainbowMan: false, sequence: 10 }, + steps: [{ trigger: '.anchor1', content: "1" }], + }, { + name: "Tour 2", + options: { rainbowMan: false, sequence: 5 }, + steps: [{ trigger: '.anchor2', content: "2" }], + }], + // Use this test in "debug" mode because the tips need to be in + // the viewport to be able to test their normal content + // (otherwise, the tips would indicate to the users that they + // have to scroll). + debug: true, + }); + + assert.containsN(document.body, '.o_tooltip', 2); + assert.strictEqual($('.o_tooltip_content:visible').text(), "2"); + + await testUtils.dom.click($('.anchor1')); + assert.containsOnce(document.body, '.o_tooltip'); + assert.strictEqual($('.o_tooltip_content:visible').text(), "2"); + + await testUtils.dom.click($('.anchor2')); + assert.containsNone(document.body, '.o_tooltip'); + + tourManager.destroy(); + }); }); });