forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			751 lines
		
	
	
	
		
			23 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			751 lines
		
	
	
	
		
			23 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* Any copyright is dedicated to the Public Domain.
 | 
						|
 * http://creativecommons.org/publicdomain/zero/1.0/ */
 | 
						|
 | 
						|
"use strict";
 | 
						|
 | 
						|
var gTestTab;
 | 
						|
var gContentAPI;
 | 
						|
 | 
						|
ChromeUtils.defineESModuleGetters(this, {
 | 
						|
  ProfileAge: "resource://gre/modules/ProfileAge.sys.mjs",
 | 
						|
  TelemetryArchiveTesting:
 | 
						|
    "resource://testing-common/TelemetryArchiveTesting.sys.mjs",
 | 
						|
  TelemetryTestUtils: "resource://testing-common/TelemetryTestUtils.sys.mjs",
 | 
						|
  UpdateUtils: "resource://gre/modules/UpdateUtils.sys.mjs",
 | 
						|
});
 | 
						|
 | 
						|
function test() {
 | 
						|
  UITourTest();
 | 
						|
}
 | 
						|
 | 
						|
var tests = [
 | 
						|
  function test_untrusted_host(done) {
 | 
						|
    loadUITourTestPage(function () {
 | 
						|
      CustomizableUI.addWidgetToArea(
 | 
						|
        "bookmarks-menu-button",
 | 
						|
        CustomizableUI.AREA_NAVBAR,
 | 
						|
        0
 | 
						|
      );
 | 
						|
      registerCleanupFunction(() =>
 | 
						|
        CustomizableUI.removeWidgetFromArea("bookmarks-menu-button")
 | 
						|
      );
 | 
						|
      let bookmarksMenu = document.getElementById("bookmarks-menu-button");
 | 
						|
      is(bookmarksMenu.open, false, "Bookmark menu should initially be closed");
 | 
						|
 | 
						|
      gContentAPI.showMenu("bookmarks");
 | 
						|
      is(
 | 
						|
        bookmarksMenu.open,
 | 
						|
        false,
 | 
						|
        "Bookmark menu should not open on a untrusted host"
 | 
						|
      );
 | 
						|
 | 
						|
      done();
 | 
						|
    }, "http://mochi.test:8888/");
 | 
						|
  },
 | 
						|
  function test_testing_host(done) {
 | 
						|
    // Add two testing origins intentionally surrounded by whitespace to be ignored.
 | 
						|
    Services.prefs.setCharPref(
 | 
						|
      "browser.uitour.testingOrigins",
 | 
						|
      "https://test1.example.org, https://test2.example.org:443 "
 | 
						|
    );
 | 
						|
 | 
						|
    registerCleanupFunction(() => {
 | 
						|
      Services.prefs.clearUserPref("browser.uitour.testingOrigins");
 | 
						|
    });
 | 
						|
    function callback(result) {
 | 
						|
      ok(result, "Callback should be called on a testing origin");
 | 
						|
      done();
 | 
						|
    }
 | 
						|
 | 
						|
    loadUITourTestPage(function () {
 | 
						|
      gContentAPI.getConfiguration("appinfo", callback);
 | 
						|
    }, "https://test2.example.org/");
 | 
						|
  },
 | 
						|
  function test_unsecure_host(done) {
 | 
						|
    loadUITourTestPage(function () {
 | 
						|
      let bookmarksMenu = document.getElementById("bookmarks-menu-button");
 | 
						|
      is(bookmarksMenu.open, false, "Bookmark menu should initially be closed");
 | 
						|
 | 
						|
      gContentAPI.showMenu("bookmarks");
 | 
						|
      is(
 | 
						|
        bookmarksMenu.open,
 | 
						|
        false,
 | 
						|
        "Bookmark menu should not open on a unsecure host"
 | 
						|
      );
 | 
						|
 | 
						|
      done();
 | 
						|
    }, "http://example.org/");
 | 
						|
  },
 | 
						|
  function test_unsecure_host_override(done) {
 | 
						|
    Services.prefs.setBoolPref("browser.uitour.requireSecure", false);
 | 
						|
    loadUITourTestPage(function () {
 | 
						|
      let highlight = document.getElementById("UITourHighlight");
 | 
						|
      is_element_hidden(highlight, "Highlight should initially be hidden");
 | 
						|
 | 
						|
      gContentAPI.showHighlight("urlbar").then(() => {
 | 
						|
        waitForElementToBeVisible(
 | 
						|
          highlight,
 | 
						|
          done,
 | 
						|
          "Highlight should be shown on a unsecure host when override pref is set"
 | 
						|
        );
 | 
						|
 | 
						|
        Services.prefs.setBoolPref("browser.uitour.requireSecure", true);
 | 
						|
      });
 | 
						|
    }, "http://example.org/");
 | 
						|
  },
 | 
						|
  function test_disabled(done) {
 | 
						|
    Services.prefs.setBoolPref("browser.uitour.enabled", false);
 | 
						|
 | 
						|
    let bookmarksMenu = document.getElementById("bookmarks-menu-button");
 | 
						|
    is(bookmarksMenu.open, false, "Bookmark menu should initially be closed");
 | 
						|
 | 
						|
    gContentAPI.showMenu("bookmarks").then(() => {
 | 
						|
      is(
 | 
						|
        bookmarksMenu.open,
 | 
						|
        false,
 | 
						|
        "Bookmark menu should not open when feature is disabled"
 | 
						|
      );
 | 
						|
 | 
						|
      Services.prefs.setBoolPref("browser.uitour.enabled", true);
 | 
						|
    });
 | 
						|
    done();
 | 
						|
  },
 | 
						|
  function test_highlight(done) {
 | 
						|
    function test_highlight_2() {
 | 
						|
      let highlight = document.getElementById("UITourHighlight");
 | 
						|
      gContentAPI.hideHighlight();
 | 
						|
 | 
						|
      waitForElementToBeHidden(
 | 
						|
        highlight,
 | 
						|
        test_highlight_3,
 | 
						|
        "Highlight should be hidden after hideHighlight()"
 | 
						|
      );
 | 
						|
    }
 | 
						|
    function test_highlight_3() {
 | 
						|
      is_element_hidden(
 | 
						|
        highlight,
 | 
						|
        "Highlight should be hidden after hideHighlight()"
 | 
						|
      );
 | 
						|
 | 
						|
      gContentAPI.showHighlight("urlbar");
 | 
						|
      waitForElementToBeVisible(
 | 
						|
        highlight,
 | 
						|
        test_highlight_4,
 | 
						|
        "Highlight should be shown after showHighlight()"
 | 
						|
      );
 | 
						|
    }
 | 
						|
    function test_highlight_4() {
 | 
						|
      let highlight = document.getElementById("UITourHighlight");
 | 
						|
      gContentAPI.showHighlight("backForward");
 | 
						|
      waitForElementToBeVisible(
 | 
						|
        highlight,
 | 
						|
        done,
 | 
						|
        "Highlight should be shown after showHighlight()"
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    let highlight = document.getElementById("UITourHighlight");
 | 
						|
    is_element_hidden(highlight, "Highlight should initially be hidden");
 | 
						|
 | 
						|
    gContentAPI.showHighlight("urlbar");
 | 
						|
    waitForElementToBeVisible(
 | 
						|
      highlight,
 | 
						|
      test_highlight_2,
 | 
						|
      "Highlight should be shown after showHighlight()"
 | 
						|
    );
 | 
						|
  },
 | 
						|
  function test_highlight_toolbar_button(done) {
 | 
						|
    function check_highlight_size() {
 | 
						|
      let panel = highlight.parentElement;
 | 
						|
      let anchor = panel.anchorNode;
 | 
						|
      let anchorRect = anchor.getBoundingClientRect();
 | 
						|
      info(
 | 
						|
        "addons target: width: " +
 | 
						|
          anchorRect.width +
 | 
						|
          " height: " +
 | 
						|
          anchorRect.height
 | 
						|
      );
 | 
						|
      let dimension = anchorRect.width;
 | 
						|
      let highlightRect = highlight.getBoundingClientRect();
 | 
						|
      info(
 | 
						|
        "highlight: width: " +
 | 
						|
          highlightRect.width +
 | 
						|
          " height: " +
 | 
						|
          highlightRect.height
 | 
						|
      );
 | 
						|
      is(
 | 
						|
        Math.round(highlightRect.width),
 | 
						|
        dimension,
 | 
						|
        "The width of the highlight should be equal to the width of the target"
 | 
						|
      );
 | 
						|
      is(
 | 
						|
        Math.round(highlightRect.height),
 | 
						|
        dimension,
 | 
						|
        "The height of the highlight should be equal to the width of the target"
 | 
						|
      );
 | 
						|
      is(
 | 
						|
        highlight.classList.contains("rounded-highlight"),
 | 
						|
        true,
 | 
						|
        "Highlight should be rounded-rectangle styled"
 | 
						|
      );
 | 
						|
      CustomizableUI.removeWidgetFromArea("home-button");
 | 
						|
      done();
 | 
						|
    }
 | 
						|
    info("Adding home button.");
 | 
						|
    CustomizableUI.addWidgetToArea("home-button", "nav-bar");
 | 
						|
    // Force the button to get layout so we can show the highlight.
 | 
						|
    document.getElementById("home-button").clientHeight;
 | 
						|
    let highlight = document.getElementById("UITourHighlight");
 | 
						|
    is_element_hidden(highlight, "Highlight should initially be hidden");
 | 
						|
 | 
						|
    gContentAPI.showHighlight("home");
 | 
						|
    waitForElementToBeVisible(
 | 
						|
      highlight,
 | 
						|
      check_highlight_size,
 | 
						|
      "Highlight should be shown after showHighlight()"
 | 
						|
    );
 | 
						|
  },
 | 
						|
  function test_highlight_addons_auto_open_close(done) {
 | 
						|
    let highlight = document.getElementById("UITourHighlight");
 | 
						|
    gContentAPI.showHighlight("addons");
 | 
						|
    waitForElementToBeVisible(
 | 
						|
      highlight,
 | 
						|
      function checkPanelIsOpen() {
 | 
						|
        isnot(PanelUI.panel.state, "closed", "Panel should have opened");
 | 
						|
        isnot(
 | 
						|
          highlight.classList.contains("rounded-highlight"),
 | 
						|
          true,
 | 
						|
          "Highlight should not be round-rectangle styled."
 | 
						|
        );
 | 
						|
 | 
						|
        let hiddenPromise = promisePanelElementHidden(window, PanelUI.panel);
 | 
						|
        // Move the highlight outside which should close the app menu.
 | 
						|
        gContentAPI.showHighlight("appMenu");
 | 
						|
        hiddenPromise.then(() => {
 | 
						|
          waitForElementToBeVisible(
 | 
						|
            highlight,
 | 
						|
            function checkPanelIsClosed() {
 | 
						|
              isnot(
 | 
						|
                PanelUI.panel.state,
 | 
						|
                "open",
 | 
						|
                "Panel should have closed after the highlight moved elsewhere."
 | 
						|
              );
 | 
						|
              done();
 | 
						|
            },
 | 
						|
            "Highlight should move to the appMenu button"
 | 
						|
          );
 | 
						|
        });
 | 
						|
      },
 | 
						|
      "Highlight should be shown after showHighlight() for fixed panel items"
 | 
						|
    );
 | 
						|
  },
 | 
						|
  function test_highlight_addons_manual_open_close(done) {
 | 
						|
    let highlight = document.getElementById("UITourHighlight");
 | 
						|
    // Manually open the app menu then show a highlight there. The menu should remain open.
 | 
						|
    let shownPromise = promisePanelShown(window);
 | 
						|
    gContentAPI.showMenu("appMenu");
 | 
						|
    shownPromise
 | 
						|
      .then(() => {
 | 
						|
        isnot(PanelUI.panel.state, "closed", "Panel should have opened");
 | 
						|
        gContentAPI.showHighlight("addons");
 | 
						|
 | 
						|
        waitForElementToBeVisible(
 | 
						|
          highlight,
 | 
						|
          function checkPanelIsStillOpen() {
 | 
						|
            isnot(PanelUI.panel.state, "closed", "Panel should still be open");
 | 
						|
 | 
						|
            // Move the highlight outside which shouldn't close the app menu since it was manually opened.
 | 
						|
            gContentAPI.showHighlight("appMenu");
 | 
						|
            waitForElementToBeVisible(
 | 
						|
              highlight,
 | 
						|
              function () {
 | 
						|
                isnot(
 | 
						|
                  PanelUI.panel.state,
 | 
						|
                  "closed",
 | 
						|
                  "Panel should remain open since UITour didn't open it in the first place"
 | 
						|
                );
 | 
						|
                gContentAPI.hideMenu("appMenu");
 | 
						|
                done();
 | 
						|
              },
 | 
						|
              "Highlight should move to the appMenu button"
 | 
						|
            );
 | 
						|
          },
 | 
						|
          "Highlight should be shown after showHighlight() for fixed panel items"
 | 
						|
        );
 | 
						|
      })
 | 
						|
      .catch(console.error);
 | 
						|
  },
 | 
						|
  function test_highlight_effect(done) {
 | 
						|
    function waitForHighlightWithEffect(highlightEl, effect, next, error) {
 | 
						|
      return waitForCondition(
 | 
						|
        () => highlightEl.getAttribute("active") == effect,
 | 
						|
        next,
 | 
						|
        error
 | 
						|
      );
 | 
						|
    }
 | 
						|
    function checkDefaultEffect() {
 | 
						|
      is(
 | 
						|
        highlight.getAttribute("active"),
 | 
						|
        "none",
 | 
						|
        "The default should be no effect"
 | 
						|
      );
 | 
						|
 | 
						|
      gContentAPI.showHighlight("urlbar", "none");
 | 
						|
      waitForHighlightWithEffect(
 | 
						|
        highlight,
 | 
						|
        "none",
 | 
						|
        checkZoomEffect,
 | 
						|
        "There should be no effect"
 | 
						|
      );
 | 
						|
    }
 | 
						|
    function checkZoomEffect() {
 | 
						|
      gContentAPI.showHighlight("urlbar", "zoom");
 | 
						|
      waitForHighlightWithEffect(
 | 
						|
        highlight,
 | 
						|
        "zoom",
 | 
						|
        () => {
 | 
						|
          let style = window.getComputedStyle(highlight);
 | 
						|
          is(
 | 
						|
            style.animationName,
 | 
						|
            "uitour-zoom",
 | 
						|
            "The animation-name should be uitour-zoom"
 | 
						|
          );
 | 
						|
          checkSameEffectOnDifferentTarget();
 | 
						|
        },
 | 
						|
        "There should be a zoom effect"
 | 
						|
      );
 | 
						|
    }
 | 
						|
    function checkSameEffectOnDifferentTarget() {
 | 
						|
      gContentAPI.showHighlight("appMenu", "wobble");
 | 
						|
      waitForHighlightWithEffect(
 | 
						|
        highlight,
 | 
						|
        "wobble",
 | 
						|
        () => {
 | 
						|
          highlight.addEventListener(
 | 
						|
            "animationstart",
 | 
						|
            function (aEvent) {
 | 
						|
              ok(
 | 
						|
                true,
 | 
						|
                "Animation occurred again even though the effect was the same"
 | 
						|
              );
 | 
						|
              checkRandomEffect();
 | 
						|
            },
 | 
						|
            { once: true }
 | 
						|
          );
 | 
						|
          gContentAPI.showHighlight("backForward", "wobble");
 | 
						|
        },
 | 
						|
        "There should be a wobble effect"
 | 
						|
      );
 | 
						|
    }
 | 
						|
    function checkRandomEffect() {
 | 
						|
      function waitForActiveHighlight(highlightEl, next, error) {
 | 
						|
        return waitForCondition(
 | 
						|
          () => highlightEl.hasAttribute("active"),
 | 
						|
          next,
 | 
						|
          error
 | 
						|
        );
 | 
						|
      }
 | 
						|
 | 
						|
      gContentAPI.hideHighlight();
 | 
						|
      gContentAPI.showHighlight("urlbar", "random");
 | 
						|
      waitForActiveHighlight(
 | 
						|
        highlight,
 | 
						|
        () => {
 | 
						|
          ok(
 | 
						|
            highlight.hasAttribute("active"),
 | 
						|
            "The highlight should be active"
 | 
						|
          );
 | 
						|
          isnot(
 | 
						|
            highlight.getAttribute("active"),
 | 
						|
            "none",
 | 
						|
            "A random effect other than none should have been chosen"
 | 
						|
          );
 | 
						|
          isnot(
 | 
						|
            highlight.getAttribute("active"),
 | 
						|
            "random",
 | 
						|
            "The random effect shouldn't be 'random'"
 | 
						|
          );
 | 
						|
          isnot(
 | 
						|
            UITour.highlightEffects.indexOf(highlight.getAttribute("active")),
 | 
						|
            -1,
 | 
						|
            "Check that a supported effect was randomly chosen"
 | 
						|
          );
 | 
						|
          done();
 | 
						|
        },
 | 
						|
        "There should be an active highlight with a random effect"
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    let highlight = document.getElementById("UITourHighlight");
 | 
						|
    is_element_hidden(highlight, "Highlight should initially be hidden");
 | 
						|
 | 
						|
    gContentAPI.showHighlight("urlbar");
 | 
						|
    waitForElementToBeVisible(
 | 
						|
      highlight,
 | 
						|
      checkDefaultEffect,
 | 
						|
      "Highlight should be shown after showHighlight()"
 | 
						|
    );
 | 
						|
  },
 | 
						|
  function test_highlight_effect_unsupported(done) {
 | 
						|
    function checkUnsupportedEffect() {
 | 
						|
      is(
 | 
						|
        highlight.getAttribute("active"),
 | 
						|
        "none",
 | 
						|
        "No effect should be used when an unsupported effect is requested"
 | 
						|
      );
 | 
						|
      done();
 | 
						|
    }
 | 
						|
 | 
						|
    let highlight = document.getElementById("UITourHighlight");
 | 
						|
    is_element_hidden(highlight, "Highlight should initially be hidden");
 | 
						|
 | 
						|
    gContentAPI.showHighlight("urlbar", "__UNSUPPORTED__");
 | 
						|
    waitForElementToBeVisible(
 | 
						|
      highlight,
 | 
						|
      checkUnsupportedEffect,
 | 
						|
      "Highlight should be shown after showHighlight()"
 | 
						|
    );
 | 
						|
  },
 | 
						|
  function test_info_1(done) {
 | 
						|
    let popup = document.getElementById("UITourTooltip");
 | 
						|
    let title = document.getElementById("UITourTooltipTitle");
 | 
						|
    let desc = document.getElementById("UITourTooltipDescription");
 | 
						|
    let icon = document.getElementById("UITourTooltipIcon");
 | 
						|
    let buttons = document.getElementById("UITourTooltipButtons");
 | 
						|
 | 
						|
    popup.addEventListener(
 | 
						|
      "popupshown",
 | 
						|
      function () {
 | 
						|
        is(
 | 
						|
          popup.anchorNode,
 | 
						|
          document.getElementById("urlbar"),
 | 
						|
          "Popup should be anchored to the urlbar"
 | 
						|
        );
 | 
						|
        is(title.textContent, "test title", "Popup should have correct title");
 | 
						|
        is(
 | 
						|
          desc.textContent,
 | 
						|
          "test text",
 | 
						|
          "Popup should have correct description text"
 | 
						|
        );
 | 
						|
        is(icon.src, "", "Popup should have no icon");
 | 
						|
        is(buttons.hasChildNodes(), false, "Popup should have no buttons");
 | 
						|
 | 
						|
        popup.addEventListener(
 | 
						|
          "popuphidden",
 | 
						|
          function () {
 | 
						|
            popup.addEventListener(
 | 
						|
              "popupshown",
 | 
						|
              function () {
 | 
						|
                done();
 | 
						|
              },
 | 
						|
              { once: true }
 | 
						|
            );
 | 
						|
 | 
						|
            gContentAPI.showInfo("urlbar", "test title", "test text");
 | 
						|
          },
 | 
						|
          { once: true }
 | 
						|
        );
 | 
						|
        gContentAPI.hideInfo();
 | 
						|
      },
 | 
						|
      { once: true }
 | 
						|
    );
 | 
						|
 | 
						|
    gContentAPI.showInfo("urlbar", "test title", "test text");
 | 
						|
  },
 | 
						|
  taskify(async function test_info_2() {
 | 
						|
    let popup = document.getElementById("UITourTooltip");
 | 
						|
    let title = document.getElementById("UITourTooltipTitle");
 | 
						|
    let desc = document.getElementById("UITourTooltipDescription");
 | 
						|
    let icon = document.getElementById("UITourTooltipIcon");
 | 
						|
    let buttons = document.getElementById("UITourTooltipButtons");
 | 
						|
 | 
						|
    await showInfoPromise("urlbar", "urlbar title", "urlbar text");
 | 
						|
 | 
						|
    is(
 | 
						|
      popup.anchorNode,
 | 
						|
      document.getElementById("urlbar"),
 | 
						|
      "Popup should be anchored to the urlbar"
 | 
						|
    );
 | 
						|
    is(title.textContent, "urlbar title", "Popup should have correct title");
 | 
						|
    is(
 | 
						|
      desc.textContent,
 | 
						|
      "urlbar text",
 | 
						|
      "Popup should have correct description text"
 | 
						|
    );
 | 
						|
    is(icon.src, "", "Popup should have no icon");
 | 
						|
    is(buttons.hasChildNodes(), false, "Popup should have no buttons");
 | 
						|
 | 
						|
    // Place the search bar in the navigation toolbar temporarily.
 | 
						|
    await SpecialPowers.pushPrefEnv({
 | 
						|
      set: [["browser.search.widget.inNavBar", true]],
 | 
						|
    });
 | 
						|
 | 
						|
    await showInfoPromise("search", "search title", "search text");
 | 
						|
 | 
						|
    is(
 | 
						|
      popup.anchorNode,
 | 
						|
      document.getElementById("searchbar"),
 | 
						|
      "Popup should be anchored to the searchbar"
 | 
						|
    );
 | 
						|
    is(title.textContent, "search title", "Popup should have correct title");
 | 
						|
    is(
 | 
						|
      desc.textContent,
 | 
						|
      "search text",
 | 
						|
      "Popup should have correct description text"
 | 
						|
    );
 | 
						|
 | 
						|
    await SpecialPowers.popPrefEnv();
 | 
						|
  }),
 | 
						|
  function test_getConfigurationVersion(done) {
 | 
						|
    function callback(result) {
 | 
						|
      ok(
 | 
						|
        typeof result.version !== "undefined",
 | 
						|
        "Check version isn't undefined."
 | 
						|
      );
 | 
						|
      is(
 | 
						|
        result.version,
 | 
						|
        Services.appinfo.version,
 | 
						|
        "Should have the same version property."
 | 
						|
      );
 | 
						|
      is(
 | 
						|
        result.defaultUpdateChannel,
 | 
						|
        UpdateUtils.getUpdateChannel(false),
 | 
						|
        "Should have the correct update channel."
 | 
						|
      );
 | 
						|
      done();
 | 
						|
    }
 | 
						|
 | 
						|
    gContentAPI.getConfiguration("appinfo", callback);
 | 
						|
  },
 | 
						|
  function test_getConfigurationDistribution(done) {
 | 
						|
    gContentAPI.getConfiguration("appinfo", result => {
 | 
						|
      ok(
 | 
						|
        typeof result.distribution !== "undefined",
 | 
						|
        "Check distribution isn't undefined."
 | 
						|
      );
 | 
						|
      // distribution id defaults to "default" for most builds, and
 | 
						|
      // "mozilla-MSIX" for MSIX builds.
 | 
						|
      is(
 | 
						|
        result.distribution,
 | 
						|
        AppConstants.platform === "win" &&
 | 
						|
          Services.sysinfo.getProperty("hasWinPackageId")
 | 
						|
          ? "mozilla-MSIX"
 | 
						|
          : "default",
 | 
						|
        'Should be "default" without preference set.'
 | 
						|
      );
 | 
						|
 | 
						|
      let defaults = Services.prefs.getDefaultBranch("distribution.");
 | 
						|
      let testDistributionID = "TestDistribution";
 | 
						|
      defaults.setCharPref("id", testDistributionID);
 | 
						|
      gContentAPI.getConfiguration("appinfo", result2 => {
 | 
						|
        ok(
 | 
						|
          typeof result2.distribution !== "undefined",
 | 
						|
          "Check distribution isn't undefined."
 | 
						|
        );
 | 
						|
        is(
 | 
						|
          result2.distribution,
 | 
						|
          testDistributionID,
 | 
						|
          "Should have the distribution as set in preference."
 | 
						|
        );
 | 
						|
 | 
						|
        done();
 | 
						|
      });
 | 
						|
    });
 | 
						|
  },
 | 
						|
  function test_getConfigurationProfileAge(done) {
 | 
						|
    gContentAPI.getConfiguration("appinfo", result => {
 | 
						|
      ok(
 | 
						|
        typeof result.profileCreatedWeeksAgo === "number",
 | 
						|
        "profileCreatedWeeksAgo should be number."
 | 
						|
      );
 | 
						|
      ok(
 | 
						|
        result.profileResetWeeksAgo === null,
 | 
						|
        "profileResetWeeksAgo should be null."
 | 
						|
      );
 | 
						|
 | 
						|
      // Set profile reset date to 15 days ago.
 | 
						|
      ProfileAge().then(profileAccessor => {
 | 
						|
        profileAccessor.recordProfileReset(
 | 
						|
          Date.now() - 15 * 24 * 60 * 60 * 1000
 | 
						|
        );
 | 
						|
        gContentAPI.getConfiguration("appinfo", result2 => {
 | 
						|
          ok(
 | 
						|
            typeof result2.profileResetWeeksAgo === "number",
 | 
						|
            "profileResetWeeksAgo should be number."
 | 
						|
          );
 | 
						|
          is(
 | 
						|
            result2.profileResetWeeksAgo,
 | 
						|
            2,
 | 
						|
            "profileResetWeeksAgo should be 2."
 | 
						|
          );
 | 
						|
          done();
 | 
						|
        });
 | 
						|
      });
 | 
						|
    });
 | 
						|
  },
 | 
						|
  function test_addToolbarButton(done) {
 | 
						|
    let placement = CustomizableUI.getPlacementOfWidget("panic-button");
 | 
						|
    is(placement, null, "default UI has panic button in the palette");
 | 
						|
 | 
						|
    gContentAPI.getConfiguration("availableTargets", data => {
 | 
						|
      let available = data.targets.includes("forget");
 | 
						|
      ok(!available, "Forget button should not be available by default");
 | 
						|
 | 
						|
      gContentAPI.addNavBarWidget("forget", () => {
 | 
						|
        info("addNavBarWidget callback successfully called");
 | 
						|
 | 
						|
        let updatedPlacement =
 | 
						|
          CustomizableUI.getPlacementOfWidget("panic-button");
 | 
						|
        is(updatedPlacement.area, CustomizableUI.AREA_NAVBAR);
 | 
						|
 | 
						|
        gContentAPI.getConfiguration("availableTargets", data2 => {
 | 
						|
          let updatedAvailable = data2.targets.includes("forget");
 | 
						|
          ok(updatedAvailable, "Forget button should now be available");
 | 
						|
 | 
						|
          // Cleanup
 | 
						|
          CustomizableUI.removeWidgetFromArea("panic-button");
 | 
						|
          done();
 | 
						|
        });
 | 
						|
      });
 | 
						|
    });
 | 
						|
  },
 | 
						|
  taskify(async function test_search() {
 | 
						|
    let defaultEngine = await Services.search.getDefault();
 | 
						|
    let visibleEngines = await Services.search.getVisibleEngines();
 | 
						|
    let expectedEngines = visibleEngines
 | 
						|
      .filter(engine => engine.identifier)
 | 
						|
      .map(engine => "searchEngine-" + engine.identifier);
 | 
						|
 | 
						|
    let data = await new Promise(resolve =>
 | 
						|
      gContentAPI.getConfiguration("search", resolve)
 | 
						|
    );
 | 
						|
    let engines = data.engines;
 | 
						|
    ok(Array.isArray(engines), "data.engines should be an array");
 | 
						|
    is(
 | 
						|
      engines.sort().toString(),
 | 
						|
      expectedEngines.sort().toString(),
 | 
						|
      "Engines should be as expected"
 | 
						|
    );
 | 
						|
 | 
						|
    is(
 | 
						|
      data.searchEngineIdentifier,
 | 
						|
      defaultEngine.identifier,
 | 
						|
      "the searchEngineIdentifier property should contain the defaultEngine's identifier"
 | 
						|
    );
 | 
						|
 | 
						|
    let someOtherEngineID = data.engines.filter(
 | 
						|
      t => t != "searchEngine-" + defaultEngine.identifier
 | 
						|
    )[0];
 | 
						|
    someOtherEngineID = someOtherEngineID.replace(/^searchEngine-/, "");
 | 
						|
 | 
						|
    Services.telemetry.clearEvents();
 | 
						|
    Services.fog.testResetFOG();
 | 
						|
 | 
						|
    await new Promise(resolve => {
 | 
						|
      let observe = function (subject, topic, verb) {
 | 
						|
        Services.obs.removeObserver(observe, "browser-search-engine-modified");
 | 
						|
        info("browser-search-engine-modified: " + verb);
 | 
						|
        if (verb == "engine-default") {
 | 
						|
          is(
 | 
						|
            Services.search.defaultEngine.identifier,
 | 
						|
            someOtherEngineID,
 | 
						|
            "correct engine was switched to"
 | 
						|
          );
 | 
						|
          resolve();
 | 
						|
        }
 | 
						|
      };
 | 
						|
      Services.obs.addObserver(observe, "browser-search-engine-modified");
 | 
						|
      registerCleanupFunction(async () => {
 | 
						|
        await Services.search.setDefault(
 | 
						|
          defaultEngine,
 | 
						|
          Ci.nsISearchService.CHANGE_REASON_UNKNOWN
 | 
						|
        );
 | 
						|
      });
 | 
						|
 | 
						|
      gContentAPI.setDefaultSearchEngine(someOtherEngineID);
 | 
						|
    });
 | 
						|
 | 
						|
    let engine = (await Services.search.getVisibleEngines()).filter(
 | 
						|
      e => e.identifier == someOtherEngineID
 | 
						|
    )[0];
 | 
						|
 | 
						|
    let submissionUrl = engine
 | 
						|
      .getSubmission("dummy")
 | 
						|
      .uri.spec.replace("dummy", "");
 | 
						|
 | 
						|
    TelemetryTestUtils.assertEvents(
 | 
						|
      [
 | 
						|
        {
 | 
						|
          object: "change_default",
 | 
						|
          value: "uitour",
 | 
						|
          extra: {
 | 
						|
            prev_id: defaultEngine.telemetryId,
 | 
						|
            new_id: engine.telemetryId,
 | 
						|
            new_name: engine.name,
 | 
						|
            new_load_path: engine.wrappedJSObject._loadPath,
 | 
						|
            // Telemetry has a limit of 80 characters.
 | 
						|
            new_sub_url: submissionUrl.slice(0, 80),
 | 
						|
          },
 | 
						|
        },
 | 
						|
      ],
 | 
						|
      { category: "search", method: "engine" }
 | 
						|
    );
 | 
						|
 | 
						|
    let snapshot = await Glean.searchEngineDefault.changed.testGetValue();
 | 
						|
    delete snapshot[0].timestamp;
 | 
						|
    Assert.deepEqual(
 | 
						|
      snapshot[0],
 | 
						|
      {
 | 
						|
        category: "search.engine.default",
 | 
						|
        name: "changed",
 | 
						|
        extra: {
 | 
						|
          change_source: "uitour",
 | 
						|
          previous_engine_id: defaultEngine.telemetryId,
 | 
						|
          new_engine_id: engine.telemetryId,
 | 
						|
          new_display_name: engine.name,
 | 
						|
          new_load_path: engine.wrappedJSObject._loadPath,
 | 
						|
          // Glean has a limit of 100 characters.
 | 
						|
          new_submission_url: submissionUrl.slice(0, 100),
 | 
						|
        },
 | 
						|
      },
 | 
						|
      "Should have received the correct event details"
 | 
						|
    );
 | 
						|
  }),
 | 
						|
  taskify(async function test_treatment_tag() {
 | 
						|
    let ac = new TelemetryArchiveTesting.Checker();
 | 
						|
    await ac.promiseInit();
 | 
						|
    await gContentAPI.setTreatmentTag("foobar", "baz");
 | 
						|
    // Wait until the treatment telemetry is sent before looking in the archive.
 | 
						|
    await BrowserTestUtils.waitForContentEvent(
 | 
						|
      gTestTab.linkedBrowser,
 | 
						|
      "mozUITourNotification",
 | 
						|
      false,
 | 
						|
      event => event.detail.event === "TreatmentTag:TelemetrySent"
 | 
						|
    );
 | 
						|
    await new Promise(resolve => {
 | 
						|
      gContentAPI.getTreatmentTag("foobar", data => {
 | 
						|
        is(data.value, "baz", "set and retrieved treatmentTag");
 | 
						|
        ac.promiseFindPing("uitour-tag", [
 | 
						|
          [["payload", "tagName"], "foobar"],
 | 
						|
          [["payload", "tagValue"], "baz"],
 | 
						|
        ]).then(
 | 
						|
          found => {
 | 
						|
            ok(found, "Telemetry ping submitted for setTreatmentTag");
 | 
						|
            resolve();
 | 
						|
          },
 | 
						|
          err => {
 | 
						|
            ok(false, "Exception finding uitour telemetry ping: " + err);
 | 
						|
            resolve();
 | 
						|
          }
 | 
						|
        );
 | 
						|
      });
 | 
						|
    });
 | 
						|
  }),
 | 
						|
 | 
						|
  // Make sure this test is last in the file so the appMenu gets left open and done will confirm it got tore down.
 | 
						|
  taskify(async function cleanupMenus() {
 | 
						|
    let shownPromise = promisePanelShown(window);
 | 
						|
    gContentAPI.showMenu("appMenu");
 | 
						|
    await shownPromise;
 | 
						|
  }),
 | 
						|
];
 |