Bug 1397701 - Should clean up UITour after closing the onboarding overlay by clicking the Skip-Tour button, r?rexboy draft
authorFischer.json <fischer.json@gmail.com>
Sun, 10 Sep 2017 19:32:34 +0800
changeset 662833 ca06ca93f89ea80a90ac9be20cf42711e5e72afc
parent 662738 bda524beac249b64aa36016800502a34073bf35a
child 730979 3a010084c6c1ea9f942dc83c33d95539e179d945
push id79199
push userbmo:fliu@mozilla.com
push dateTue, 12 Sep 2017 05:19:41 +0000
reviewersrexboy
bugs1397701
milestone57.0a1
Bug 1397701 - Should clean up UITour after closing the onboarding overlay by clicking the Skip-Tour button, r?rexboy MozReview-Commit-ID: 5dkGDCKPete
browser/extensions/onboarding/content/onboarding-tour-agent.js
browser/extensions/onboarding/test/browser/browser_onboarding_uitour.js
browser/extensions/onboarding/test/browser/head.js
--- a/browser/extensions/onboarding/content/onboarding-tour-agent.js
+++ b/browser/extensions/onboarding/content/onboarding-tour-agent.js
@@ -52,21 +52,16 @@ let onClick = evt => {
       Mozilla.UITour.showMenu("urlbar");
       break;
     case "onboarding-tour-sync-button":
       let emailInput = document.getElementById("onboarding-tour-sync-email-input");
       if (emailInput.checkValidity()) {
         Mozilla.UITour.showFirefoxAccounts(null, emailInput.value);
       }
       break;
-    case "onboarding-overlay":
-    case "onboarding-overlay-close-btn":
-      // Dismiss any highlights if a user tries to close the dialog.
-      Mozilla.UITour.hideHighlight();
-      break;
   }
   let classList = evt.target.classList;
   // On keyboard navigation the target would be .onboarding-tour-item.
   // On mouse clicking the target would be .onboarding-tour-item-container.
   if (classList.contains("onboarding-tour-item") || classList.contains("onboarding-tour-item-container")) {
     Mozilla.UITour.hideHighlight(); // Clean up UITour if a user tries to change to other tours.
   }
 };
@@ -78,12 +73,18 @@ overlay.addEventListener("keypress", e =
   let classList = target.classList;
   if ((key == " " || key == "Enter") &&
       // On keyboard navigation the target would be .onboarding-tour-item.
       // On mouse clicking the target would be .onboarding-tour-item-container.
       (classList.contains("onboarding-tour-item") || classList.contains("onboarding-tour-item-container"))) {
     Mozilla.UITour.hideHighlight(); // Clean up UITour if a user tries to change to other tours.
   }
 });
+let overlayObserver = new MutationObserver(mutations => {
+  if (!overlay.classList.contains("onboarding-opened")) {
+    Mozilla.UITour.hideHighlight(); // Clean up UITour if a user tries to close the dialog.
+  }
+});
+overlayObserver.observe(overlay, { attributes: true });
 document.getElementById("onboarding-overlay-button").addEventListener("Agent:Destroy", () => Mozilla.UITour.hideHighlight());
 document.addEventListener("Agent:CanSetDefaultBrowserInBackground", onCanSetDefaultBrowserInBackground);
 
 })();
--- a/browser/extensions/onboarding/test/browser/browser_onboarding_uitour.js
+++ b/browser/extensions/onboarding/test/browser/browser_onboarding_uitour.js
@@ -13,22 +13,74 @@ function promisePopupChange(popup, expec
 }
 
 async function promiseOpenOnboardingOverlay(tab) {
   await promiseOnboardingOverlayLoaded(tab.linkedBrowser);
   await BrowserTestUtils.synthesizeMouseAtCenter("#onboarding-overlay-button", {}, tab.linkedBrowser);
   return promiseOnboardingOverlayOpened(tab.linkedBrowser);
 }
 
-async function triggerCustomizeUITourHighlight(tab) {
+async function triggerUITourHighlight(tourName, tab) {
   await promiseOpenOnboardingOverlay(tab);
-  BrowserTestUtils.synthesizeMouseAtCenter("#onboarding-tour-customize", {}, tab.linkedBrowser);
-  BrowserTestUtils.synthesizeMouseAtCenter("#onboarding-tour-customize-button", {}, tab.linkedBrowser);
+  BrowserTestUtils.synthesizeMouseAtCenter(`#onboarding-tour-${tourName}`, {}, tab.linkedBrowser);
+  BrowserTestUtils.synthesizeMouseAtCenter(`#onboarding-tour-${tourName}-button`, {}, tab.linkedBrowser);
 }
 
+add_task(async function test_clean_up_uitour_after_closing_overlay() {
+  resetOnboardingDefaultState();
+  await SpecialPowers.pushPrefEnv({set: [
+    ["browser.onboarding.newtour", "library"],
+  ]});
+
+  // Trigger UITour showHighlight
+  let highlight = document.getElementById("UITourHighlightContainer");
+  let highlightOpenPromise = promisePopupChange(highlight, "open");
+  let tab = await openTab(ABOUT_NEWTAB_URL);
+  await triggerUITourHighlight("library", tab);
+  await highlightOpenPromise;
+  is(highlight.state, "open", "Should show UITour highlight");
+  is(highlight.getAttribute("targetName"), "library", "UITour should highlight library");
+
+  // Close the overlay by clicking the overlay
+  let highlightClosePromise = promisePopupChange(highlight, "closed");
+  BrowserTestUtils.synthesizeMouseAtPoint(2, 2, {}, tab.linkedBrowser);
+  await promiseOnboardingOverlayClosed(tab.linkedBrowser);
+  await highlightClosePromise;
+  is(highlight.state, "closed", "Should close UITour highlight after closing the overlay by clicking the overlay");
+
+  // Trigger UITour showHighlight
+  highlightOpenPromise = promisePopupChange(highlight, "open");
+  await triggerUITourHighlight("library", tab);
+  await highlightOpenPromise;
+  is(highlight.state, "open", "Should show UITour highlight");
+  is(highlight.getAttribute("targetName"), "library", "UITour should highlight library");
+
+  // Close the overlay by clicking the overlay close button
+  highlightClosePromise = promisePopupChange(highlight, "closed");
+  BrowserTestUtils.synthesizeMouseAtCenter("#onboarding-overlay-close-btn", {}, tab.linkedBrowser);
+  await promiseOnboardingOverlayClosed(tab.linkedBrowser);
+  await highlightClosePromise;
+  is(highlight.state, "closed", "Should close UITour highlight after closing the overlay by clicking the overlay close button");
+
+  // Trigger UITour showHighlight again
+  highlightOpenPromise = promisePopupChange(highlight, "open");
+  await triggerUITourHighlight("library", tab);
+  await highlightOpenPromise;
+  is(highlight.state, "open", "Should show UITour highlight");
+  is(highlight.getAttribute("targetName"), "library", "UITour should highlight library");
+
+  // Close the overlay by clicking the skip-tour button
+  highlightClosePromise = promisePopupChange(highlight, "closed");
+  BrowserTestUtils.synthesizeMouseAtCenter("#onboarding-skip-tour-btn", {}, tab.linkedBrowser);
+  await promiseOnboardingOverlayClosed(tab.linkedBrowser);
+  await highlightClosePromise;
+  is(highlight.state, "closed", "Should close UITour highlight after closing the overlay by clicking the skip-tour button");
+  await BrowserTestUtils.removeTab(tab);
+});
+
 add_task(async function test_clean_up_uitour_after_navigating_to_other_tour_by_keyboard() {
   resetOnboardingDefaultState();
   await SpecialPowers.pushPrefEnv({set: [
     ["browser.onboarding.newtour", "singlesearch,customize"],
   ]});
 
   let tab = await openTab(ABOUT_NEWTAB_URL);
   await promiseOpenOnboardingOverlay(tab);
@@ -62,17 +114,17 @@ add_task(async function test_clean_up_ui
   await SpecialPowers.pushPrefEnv({set: [
     ["browser.onboarding.newtour", "singlesearch,customize"],
   ]});
 
   // Navigate to the Customize tour to trigger UITour showHighlight
   let highlight = document.getElementById("UITourHighlightContainer");
   let highlightOpenPromise = promisePopupChange(highlight, "open");
   let tab = await openTab(ABOUT_NEWTAB_URL);
-  await triggerCustomizeUITourHighlight(tab);
+  await triggerUITourHighlight("customize", tab);
   await highlightOpenPromise;
   is(highlight.state, "open", "Should show UITour highlight");
   is(highlight.getAttribute("targetName"), "customize", "UITour should highlight customize");
 
   // Navigate to the Single-Search tour
   let highlightClosePromise = promisePopupChange(highlight, "closed");
   BrowserTestUtils.synthesizeMouseAtCenter("#onboarding-tour-singlesearch", {}, tab.linkedBrowser);
   await highlightClosePromise;
@@ -85,17 +137,17 @@ add_task(async function test_clean_up_ui
   await SpecialPowers.pushPrefEnv({set: [
     ["browser.onboarding.newtour", "singlesearch,customize"],
   ]});
 
   // Trigger UITour showHighlight
   let highlight = document.getElementById("UITourHighlightContainer");
   let highlightOpenPromise = promisePopupChange(highlight, "open");
   let tab = await openTab(ABOUT_NEWTAB_URL);
-  await triggerCustomizeUITourHighlight(tab);
+  await triggerUITourHighlight("customize", tab);
   await highlightOpenPromise;
   is(highlight.state, "open", "Should show UITour highlight");
   is(highlight.getAttribute("targetName"), "customize", "UITour should highlight customize");
 
   // Load another page to unload the current page
   let highlightClosePromise = promisePopupChange(highlight, "closed");
   await BrowserTestUtils.loadURI(tab.linkedBrowser, "http://example.com");
   await highlightClosePromise;
@@ -108,17 +160,17 @@ add_task(async function test_clean_up_ui
   await SpecialPowers.pushPrefEnv({set: [
     ["browser.onboarding.newtour", "singlesearch,customize"],
   ]});
 
   // Trigger UITour showHighlight
   let highlight = document.getElementById("UITourHighlightContainer");
   let highlightOpenPromise = promisePopupChange(highlight, "open");
   let tab = await openTab(ABOUT_NEWTAB_URL);
-  await triggerCustomizeUITourHighlight(tab);
+  await triggerUITourHighlight("customize", tab);
   await highlightOpenPromise;
   is(highlight.state, "open", "Should show UITour highlight");
   is(highlight.getAttribute("targetName"), "customize", "UITour should highlight customize");
 
   // Resize window to destroy the onboarding tour
   const originalWidth = window.innerWidth;
   let highlightClosePromise = promisePopupChange(highlight, "closed");
   window.innerWidth = 300;
--- a/browser/extensions/onboarding/test/browser/head.js
+++ b/browser/extensions/onboarding/test/browser/head.js
@@ -84,17 +84,17 @@ function promiseOnboardingOverlayLoaded(
   return ContentTask.spawn(browser, {}, isLoaded);
 }
 
 function promiseOnboardingOverlayOpened(browser) {
   return BrowserTestUtils.waitForCondition(() =>
     ContentTask.spawn(browser, {}, () =>
       content.document.querySelector("#onboarding-overlay").classList.contains(
         "onboarding-opened")),
-    "Should close onboarding overlay",
+    "Should open onboarding overlay",
     100,
     30
   );
 }
 
 function promiseOnboardingOverlayClosed(browser) {
   return BrowserTestUtils.waitForCondition(() =>
     ContentTask.spawn(browser, {}, () =>