Bug 1397744 - Show the Sync animation immediately after clicking the manual sync button. r?markh draft
authorEdouard Oger <eoger@fastmail.com>
Wed, 20 Sep 2017 13:16:19 -0400
changeset 675160 74a77497acd3dffa9848d401da9556599fc6e344
parent 674765 294f332a35538940469b1a2576615ff5ffe1e016
child 734531 507288d03a54639979cd1c05e0eff1612166fa70
push id83055
push userbmo:eoger@fastmail.com
push dateWed, 04 Oct 2017 22:36:36 +0000
reviewersmarkh
bugs1397744
milestone58.0a1
Bug 1397744 - Show the Sync animation immediately after clicking the manual sync button. r?markh MozReview-Commit-ID: AIBjAZZlYX6
browser/base/content/browser-sync.js
browser/components/customizableui/test/browser_synced_tabs_menu.js
--- a/browser/base/content/browser-sync.js
+++ b/browser/base/content/browser-sync.js
@@ -519,16 +519,17 @@ var gSync = {
   // doSync forces a sync - it *does not* return a promise as it is called
   // via the various UI components.
   doSync() {
     if (!UIState.isReady()) {
       return;
     }
     const state = UIState.get();
     if (state.status == UIState.STATUS_SIGNED_IN) {
+      this.updateSyncStatus({ syncing: true });
       setTimeout(() => Weave.Service.errorHandler.syncAndReportErrors(), 0);
     }
   },
 
   openPrefs(entryPoint = "syncbutton", origin = undefined) {
     window.openPreferences("paneSync", { origin, urlParams: { entrypoint: entryPoint } });
   },
 
--- a/browser/components/customizableui/test/browser_synced_tabs_menu.js
+++ b/browser/components/customizableui/test/browser_synced_tabs_menu.js
@@ -2,16 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 requestLongerTimeout(2);
 
 let {SyncedTabs} = Cu.import("resource://services-sync/SyncedTabs.jsm", {});
+let {UIState} = Cu.import("resource://services-sync/UIState.jsm", {});
 
 XPCOMUtils.defineLazyModuleGetter(this, "UITour", "resource:///modules/UITour.jsm");
 
 // These are available on the widget implementation, but it seems impossible
 // to grab that impl at runtime.
 const DECKINDEX_TABS = 0;
 const DECKINDEX_TABSDISABLED = 1;
 const DECKINDEX_FETCHING = 2;
@@ -37,28 +38,26 @@ let mockedInternal = {
   hasSyncedThisSession: false,
 };
 
 
 add_task(async function setup() {
   let oldInternal = SyncedTabs._internal;
   SyncedTabs._internal = mockedInternal;
 
-  // This test hacks some observer states to simulate a user being signed
-  // in to Sync - restore them when the test completes.
-  let initialObserverStates = {};
-  for (let id of ["sync-reauth-state", "sync-setup-state", "sync-syncnow-state"]) {
-    initialObserverStates[id] = document.getElementById(id).hidden;
-  }
+  let origNotifyStateUpdated = UIState._internal.notifyStateUpdated;
+  // Sync start-up will interfere with our tests, don't let UIState send UI updates.
+  UIState._internal.notifyStateUpdated = () => {};
+
+  // Force gSync initialization
+  gSync.init();
 
   registerCleanupFunction(() => {
+    UIState._internal.notifyStateUpdated = origNotifyStateUpdated;
     SyncedTabs._internal = oldInternal;
-    for (let [id, initial] of Object.entries(initialObserverStates)) {
-      document.getElementById(id).hidden = initial;
-    }
   });
 });
 
 // The test expects the about:preferences#sync page to open in the current tab
 async function openPrefsFromMenuPanel(expectedPanelId, entryPoint) {
   info("Check Sync button functionality");
   Services.prefs.setCharPref("identity.fxaccounts.remote.signup.uri", "http://example.com/");
   CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
@@ -130,41 +129,34 @@ async function asyncCleanup() {
   // restore the tabs
   BrowserTestUtils.addTab(gBrowser, initialLocation);
   gBrowser.removeTab(newTab);
   UITour.tourBrowsersByWindow.delete(window);
 }
 
 // When Sync is not setup.
 add_task(async function() {
-  document.getElementById("sync-reauth-state").hidden = true;
-  document.getElementById("sync-setup-state").hidden = false;
-  document.getElementById("sync-syncnow-state").hidden = true;
-  await openPrefsFromMenuPanel("PanelUI-remotetabs-setupsync", "synced-tabs")
+  gSync.updateAllUI({ status: UIState.STATUS_NOT_CONFIGURED });
+  await openPrefsFromMenuPanel("PanelUI-remotetabs-setupsync", "synced-tabs");
 });
 add_task(asyncCleanup);
 
 // When Sync is configured in a "needs reauthentication" state.
 add_task(async function() {
-  // configure our broadcasters so we are in the right state.
-  document.getElementById("sync-reauth-state").hidden = false;
-  document.getElementById("sync-setup-state").hidden = true;
-  document.getElementById("sync-syncnow-state").hidden = true;
+  gSync.updateAllUI({ status: UIState.STATUS_LOGIN_FAILED, email: "foo@bar.com" });
   await openPrefsFromMenuPanel("PanelUI-remotetabs-reauthsync", "synced-tabs")
 });
 
 // Test the mobile promo links
 add_task(async function() {
   // change the preferences for the mobile links.
   Services.prefs.setCharPref("identity.mobilepromo.android", "http://example.com/?os=android&tail=");
   Services.prefs.setCharPref("identity.mobilepromo.ios", "http://example.com/?os=ios&tail=");
 
-  document.getElementById("sync-reauth-state").hidden = true;
-  document.getElementById("sync-setup-state").hidden = true;
-  document.getElementById("sync-syncnow-state").hidden = false;
+  gSync.updateAllUI({ status: UIState.STATUS_SIGNED_IN, email: "foo@bar.com" });
 
   let syncPanel = document.getElementById("PanelUI-remotetabs");
   let links = syncPanel.querySelectorAll(".remotetabs-promo-link");
 
   is(links.length, 2, "found 2 links as expected");
 
   // test each link and left and middle mouse buttons
   for (let link of links) {
@@ -205,20 +197,17 @@ add_task(async function() {
   await hideOverflow();
 
   Services.prefs.clearUserPref("identity.mobilepromo.android");
   Services.prefs.clearUserPref("identity.mobilepromo.ios");
 });
 
 // Test the "Sync Now" button
 add_task(async function() {
-  // configure our broadcasters so we are in the right state.
-  document.getElementById("sync-reauth-state").hidden = true;
-  document.getElementById("sync-setup-state").hidden = true;
-  document.getElementById("sync-syncnow-state").hidden = false;
+  gSync.updateAllUI({ status: UIState.STATUS_SIGNED_IN, email: "foo@bar.com" });
 
   await document.getElementById("nav-bar").overflowable.show();
   let tabsUpdatedPromise = promiseObserverNotified("synced-tabs-menu:test:tabs-updated");
   let syncPanel = document.getElementById("PanelUI-remotetabs");
   let viewShownPromise = BrowserTestUtils.waitForEvent(syncPanel, "ViewShown");
   let syncButton = document.getElementById("sync-button");
   syncButton.click();
   await Promise.all([tabsUpdatedPromise, viewShownPromise]);
@@ -227,32 +216,21 @@ add_task(async function() {
   let subpanel = document.getElementById("PanelUI-remotetabs-main")
   ok(!subpanel.hidden, "main pane is visible");
   let deck = document.getElementById("PanelUI-remotetabs-deck");
 
   // The widget is still fetching tabs, as we've neutered everything that
   // provides them
   is(deck.selectedIndex, DECKINDEX_FETCHING, "first deck entry is visible");
 
-  let syncNowButton = document.getElementById("PanelUI-remotetabs-syncnow");
-
-  let didSync = false;
-  let oldDoSync = gSync.doSync;
-  gSync.doSync = function() {
-    didSync = true;
-    mockedInternal.hasSyncedThisSession = true;
-    gSync.doSync = oldDoSync;
-  }
-  syncNowButton.click();
-  ok(didSync, "clicking the button called the correct function");
-
   // Tell the widget there are tabs available, but with zero clients.
   mockedInternal.getTabClients = () => {
     return Promise.resolve([]);
   }
+  mockedInternal.hasSyncedThisSession = true;
   await updateTabsPanel();
   // The UI should be showing the "no clients" pane.
   is(deck.selectedIndex, DECKINDEX_NOCLIENTS, "no-clients deck entry is visible");
 
   // Tell the widget there are tabs available - we have 3 clients, one with no
   // tabs.
   mockedInternal.getTabClients = () => {
     return Promise.resolve([
@@ -344,16 +322,28 @@ add_task(async function() {
   // There is a single node saying there's no tabs for the client.
   node = node.nextSibling;
   is(node.nodeName, "label", "node is a label");
   is(node.getAttribute("itemtype"), "", "node is neither a tab nor a client");
 
   node = node.nextSibling;
   is(node, null, "no more entries");
 
+  let didSync = false;
+  let oldDoSync = gSync.doSync;
+  gSync.doSync = function() {
+    didSync = true;
+    gSync.doSync = oldDoSync;
+  }
+
+  let syncNowButton = document.getElementById("PanelUI-remotetabs-syncnow");
+  is(syncNowButton.disabled, false);
+  syncNowButton.click();
+  ok(didSync, "clicking the button called the correct function");
+
   await hideOverflow();
 });
 
 // Test the pagination capabilities (Show More/All tabs)
 add_task(async function() {
   mockedInternal.getTabClients = () => {
     return Promise.resolve([
       {
@@ -370,20 +360,17 @@ add_task(async function() {
             allTabsDesktop.push({ title: "Tab #" + i });
           }
           return allTabsDesktop;
         }(),
       }
     ]);
   };
 
-  // configure our broadcasters so we are in the right state.
-  document.getElementById("sync-reauth-state").hidden = true;
-  document.getElementById("sync-setup-state").hidden = true;
-  document.getElementById("sync-syncnow-state").hidden = false;
+  gSync.updateAllUI({ status: UIState.STATUS_SIGNED_IN, email: "foo@bar.com" });
 
   await document.getElementById("nav-bar").overflowable.show();
   let tabsUpdatedPromise = promiseObserverNotified("synced-tabs-menu:test:tabs-updated");
   let syncPanel = document.getElementById("PanelUI-remotetabs");
   let viewShownPromise = BrowserTestUtils.waitForEvent(syncPanel, "ViewShown");
   let syncButton = document.getElementById("sync-button");
   syncButton.click();
   await Promise.all([tabsUpdatedPromise, viewShownPromise]);