Bug 1185579 - UITour: Make the "accountStatus" target use the FxA avatar when logged in. r=markh
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Tue, 04 Aug 2015 22:55:21 -0700
changeset 288073 1ba8b8c60de6c5435d948e877b1f6ccc9b8aeab8
parent 288072 b5f93878cfcd6d889678fc9bc6462cd5a13f0ee9
child 288074 3ae9930347ad077a9c78327fe79699a2b55a0e7d
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmarkh
bugs1185579
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1185579 - UITour: Make the "accountStatus" target use the FxA avatar when logged in. r=markh
browser/components/uitour/UITour.jsm
browser/components/uitour/test/browser.ini
browser/components/uitour/test/browser_fxa.js
browser/components/uitour/test/head.js
--- a/browser/components/uitour/UITour.jsm
+++ b/browser/components/uitour/UITour.jsm
@@ -93,21 +93,30 @@ this.UITour = {
   availableTargetsCache: new WeakMap(),
 
   _annotationPanelMutationObservers: new WeakMap(),
 
   highlightEffects: ["random", "wobble", "zoom", "color"],
   targets: new Map([
     ["accountStatus", {
       query: (aDocument) => {
+        // If the user is logged in, use the avatar element.
+        let fxAFooter = aDocument.getElementById("PanelUI-footer-fxa");
+        if (fxAFooter.getAttribute("fxastatus")) {
+          return aDocument.getElementById("PanelUI-fxa-avatar");
+        }
+
+        // Otherwise use the sync setup icon.
         let statusButton = aDocument.getElementById("PanelUI-fxa-label");
         return aDocument.getAnonymousElementByAttribute(statusButton,
                                                         "class",
                                                         "toolbarbutton-icon");
       },
+      // This is a fake widgetName starting with the "PanelUI-" prefix so we know
+      // to automatically open the appMenu when annotating this target.
       widgetName: "PanelUI-fxa-label",
     }],
     ["addons",      {query: "#add-ons-button"}],
     ["appMenu",     {
       addTargetListener: (aDocument, aCallback) => {
         let panelPopup = aDocument.getElementById("PanelUI-popup");
         panelPopup.addEventListener("popupshown", aCallback);
       },
--- a/browser/components/uitour/test/browser.ini
+++ b/browser/components/uitour/test/browser.ini
@@ -2,16 +2,18 @@
 support-files =
   head.js
   image.png
   uitour.html
   ../UITour-lib.js
 
 [browser_backgroundTab.js]
 skip-if = e10s # Bug 941428 - UITour.jsm not e10s friendly
+[browser_fxa.js]
+skip-if = e10s || debug || asan # Bug 1073247 - UITour tests not e10s friendly # updateAppMenuItem leaks
 [browser_no_tabs.js]
 [browser_openPreferences.js]
 skip-if = e10s # Bug 1073247 - UITour tests not e10s friendly
 [browser_openSearchPanel.js]
 skip-if = true # Bug 1113038 - Intermittent "Popup was opened"
 [browser_trackingProtection.js]
 skip-if = os == "linux" # Intermittent NS_ERROR_NOT_AVAILABLE [nsIUrlClassifierDBService.beginUpdate]
 tag = trackingprotection
new file mode 100644
--- /dev/null
+++ b/browser/components/uitour/test/browser_fxa.js
@@ -0,0 +1,68 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
+                                  "resource://gre/modules/FxAccounts.jsm");
+
+let gTestTab;
+let gContentAPI;
+let gContentWindow;
+
+function test() {
+  UITourTest();
+}
+
+registerCleanupFunction(function*() {
+  yield signOut();
+  gFxAccounts.updateAppMenuItem();
+});
+
+let tests = [
+  taskify(function* test_highlight_accountStatus_loggedOut() {
+    let userData = yield fxAccounts.getSignedInUser();
+    is(userData, null, "Not logged in initially");
+    yield showMenuPromise("appMenu");
+    yield showHighlightPromise("accountStatus");
+    let highlight = document.getElementById("UITourHighlightContainer");
+    is(highlight.getAttribute("targetName"), "accountStatus", "Correct highlight target");
+  }),
+
+  taskify(function* test_highlight_accountStatus_loggedIn() {
+    yield setSignedInUser();
+    let userData = yield fxAccounts.getSignedInUser();
+    isnot(userData, null, "Logged in now");
+    gFxAccounts.updateAppMenuItem(); // Causes a leak
+    yield showMenuPromise("appMenu");
+    yield showHighlightPromise("accountStatus");
+    let highlight = document.getElementById("UITourHighlightContainer");
+    is(highlight.popupBoxObject.anchorNode.id, "PanelUI-fxa-avatar", "Anchored on avatar");
+    is(highlight.getAttribute("targetName"), "accountStatus", "Correct highlight target");
+  }),
+];
+
+// Helpers copied from browser_aboutAccounts.js
+// watch out - these will fire observers which if you aren't careful, may
+// interfere with the tests.
+function setSignedInUser(data) {
+  if (!data) {
+    data = {
+      email: "foo@example.com",
+      uid: "1234@lcip.org",
+      assertion: "foobar",
+      sessionToken: "dead",
+      kA: "beef",
+      kB: "cafe",
+      verified: true
+    };
+  }
+ return fxAccounts.setSignedInUser(data);
+}
+
+function signOut() {
+  // we always want a "localOnly" signout here...
+  return fxAccounts.signOut(true);
+}
--- a/browser/components/uitour/test/head.js
+++ b/browser/components/uitour/test/head.js
@@ -134,16 +134,22 @@ function hideInfoPromise(...args) {
 }
 
 function showInfoPromise(...args) {
   let popup = document.getElementById("UITourTooltip");
   gContentAPI.showInfo.apply(gContentAPI, args);
   return promisePanelElementShown(window, popup);
 }
 
+function showHighlightPromise(...args) {
+  let popup = document.getElementById("UITourHighlightContainer");
+  gContentAPI.showHighlight.apply(gContentAPI, args);
+  return promisePanelElementShown(window, popup);
+}
+
 function showMenuPromise(name) {
   return new Promise(resolve => {
     gContentAPI.showMenu(name, () => resolve());
   });
 }
 
 function waitForCallbackResultPromise() {
   return waitForConditionPromise(() => {