diff --git a/addons/web_tour/static/src/tour_service/tour_service.js b/addons/web_tour/static/src/tour_service/tour_service.js index 6380af3fae7..6522094400b 100644 --- a/addons/web_tour/static/src/tour_service/tour_service.js +++ b/addons/web_tour/static/src/tour_service/tour_service.js @@ -66,14 +66,13 @@ export const tourService = { tours[name] = { name: tour.saveAs || name, get steps() { - if(typeof tour.steps === "function") { + if (typeof tour.steps === "function") { return tour.steps().map((step) => { step.shadow_dom = step.shadow_dom ?? tour.shadow_dom; return step; }); - } - else { - throw new Error(`tour.steps has to be a function that returns TourStep[]`) + } else { + throw new Error(`tour.steps has to be a function that returns TourStep[]`); } }, shadow_dom: tour.shadow_dom, @@ -106,6 +105,8 @@ export const tourService = { const consumedTours = new Set(session.web_tours); const pointers = reactive({}); + /** @type {Set} */ + const runningTours = new Set(); function createPointer(tourName, config) { const { state: pointerState, methods } = createPointerState(); @@ -214,6 +215,7 @@ export const tourService = { pointer.stop(); // Used to signal the python test runner that the tour finished without error. browser.console.log("test successful"); + runningTours.delete(name); }, }); } @@ -259,6 +261,10 @@ export const tourService = { } function startTour(tourName, options = {}) { + if (runningTours.has(tourName)) { + return; + } + runningTours.add(tourName); const defaultOptions = { stepDelay: 0, keepWatchBrowser: false, @@ -303,6 +309,10 @@ export const tourService = { } function resumeTour(tourName) { + if (runningTours.has(tourName)) { + return; + } + runningTours.add(tourName); const tour = tours[tourName]; const stepDelay = tourState.get(tourName, "stepDelay"); const keepWatchBrowser = tourState.get(tourName, "keepWatchBrowser"); diff --git a/addons/web_tour/static/tests/tour_service_tests.js b/addons/web_tour/static/tests/tour_service_tests.js index 66186929af7..8543ec3b066 100644 --- a/addons/web_tour/static/tests/tour_service_tests.js +++ b/addons/web_tour/static/tests/tour_service_tests.js @@ -365,7 +365,7 @@ QUnit.module("Tour service", (hooks) => { QUnit.test("perform edit on next step", async function (assert) { registry.category("web_tour.tours").add("tour1", { sequence: 10, - steps:() => [ + steps: () => [ { trigger: ".interval input", }, @@ -435,6 +435,15 @@ QUnit.module("Tour service", (hooks) => { }); QUnit.test("should show only 1 pointer at a time", async function (assert) { + const storage = new Map(); + patchWithCleanup(browser.localStorage, { + getItem: (key) => storage.get(key), + setItem: (key, value) => storage.set(key, value), + removeItem: (key) => storage.delete(key), + tour__tour1__sequence: 0, + tour__tour2__sequence: 0, + }); + registry.category("web_tour.tours").add("tour1", { sequence: 10, steps: () => [