summaryrefslogtreecommitdiffstats
path: root/browser/components/customizableui/test/browser_967000_button_sync.js
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /browser/components/customizableui/test/browser_967000_button_sync.js
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'browser/components/customizableui/test/browser_967000_button_sync.js')
-rw-r--r--browser/components/customizableui/test/browser_967000_button_sync.js335
1 files changed, 335 insertions, 0 deletions
diff --git a/browser/components/customizableui/test/browser_967000_button_sync.js b/browser/components/customizableui/test/browser_967000_button_sync.js
new file mode 100644
index 000000000..15a3235e0
--- /dev/null
+++ b/browser/components/customizableui/test/browser_967000_button_sync.js
@@ -0,0 +1,335 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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", {});
+
+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;
+const DECKINDEX_NOCLIENTS = 3;
+
+var initialLocation = gBrowser.currentURI.spec;
+var newTab = null;
+
+// A helper to notify there are new tabs. Returns a promise that is resolved
+// once the UI has been updated.
+function updateTabsPanel() {
+ let promiseTabsUpdated = promiseObserverNotified("synced-tabs-menu:test:tabs-updated");
+ Services.obs.notifyObservers(null, SyncedTabs.TOPIC_TABS_CHANGED, null);
+ return promiseTabsUpdated;
+}
+
+// This is the mock we use for SyncedTabs.jsm - tests may override various
+// functions.
+let mockedInternal = {
+ get isConfiguredToSyncTabs() { return true; },
+ getTabClients() { return []; },
+ syncTabs() {},
+ hasSyncedThisSession: false,
+};
+
+
+add_task(function* setup() {
+ let oldInternal = SyncedTabs._internal;
+ SyncedTabs._internal = mockedInternal;
+
+ registerCleanupFunction(() => {
+ SyncedTabs._internal = oldInternal;
+ });
+});
+
+// The test expects the about:preferences#sync page to open in the current tab
+function* openPrefsFromMenuPanel(expectedPanelId, entryPoint) {
+ info("Check Sync button functionality");
+ Services.prefs.setCharPref("identity.fxaccounts.remote.signup.uri", "http://example.com/");
+
+ // add the Sync button to the panel
+ CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
+
+ // check the button's functionality
+ yield PanelUI.show();
+
+ if (entryPoint == "uitour") {
+ UITour.tourBrowsersByWindow.set(window, new Set());
+ UITour.tourBrowsersByWindow.get(window).add(gBrowser.selectedBrowser);
+ }
+
+ let syncButton = document.getElementById("sync-button");
+ ok(syncButton, "The Sync button was added to the Panel Menu");
+
+ syncButton.click();
+ let syncPanel = document.getElementById("PanelUI-remotetabs");
+ ok(syncPanel.getAttribute("current"), "Sync Panel is in view");
+
+ // Sync is not configured - verify that state is reflected.
+ let subpanel = document.getElementById(expectedPanelId)
+ ok(!subpanel.hidden, "sync setup element is visible");
+
+ // Find and click the "setup" button.
+ let setupButton = subpanel.querySelector(".PanelUI-remotetabs-prefs-button");
+ setupButton.click();
+
+ let deferred = Promise.defer();
+ let handler = (e) => {
+ if (e.originalTarget != gBrowser.selectedBrowser.contentDocument ||
+ e.target.location.href == "about:blank") {
+ info("Skipping spurious 'load' event for " + e.target.location.href);
+ return;
+ }
+ gBrowser.selectedBrowser.removeEventListener("load", handler, true);
+ deferred.resolve();
+ }
+ gBrowser.selectedBrowser.addEventListener("load", handler, true);
+
+ yield deferred.promise;
+ newTab = gBrowser.selectedTab;
+
+ is(gBrowser.currentURI.spec, "about:preferences?entrypoint=" + entryPoint + "#sync",
+ "Firefox Sync preference page opened with `menupanel` entrypoint");
+ ok(!isPanelUIOpen(), "The panel closed");
+
+ if (isPanelUIOpen()) {
+ let panelHidePromise = promisePanelHidden(window);
+ PanelUI.hide();
+ yield panelHidePromise;
+ }
+}
+
+function* asyncCleanup() {
+ Services.prefs.clearUserPref("identity.fxaccounts.remote.signup.uri");
+ // reset the panel UI to the default state
+ yield resetCustomization();
+ ok(CustomizableUI.inDefaultState, "The panel UI is in default state again.");
+
+ // restore the tabs
+ gBrowser.addTab(initialLocation);
+ gBrowser.removeTab(newTab);
+ UITour.tourBrowsersByWindow.delete(window);
+}
+
+// When Sync is not setup.
+add_task(() => openPrefsFromMenuPanel("PanelUI-remotetabs-setupsync", "synced-tabs"));
+add_task(asyncCleanup);
+
+// When Sync is configured in a "needs reauthentication" state.
+add_task(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;
+ yield openPrefsFromMenuPanel("PanelUI-remotetabs-reauthsync", "synced-tabs")
+});
+
+// Test the mobile promo links
+add_task(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=");
+
+ mockedInternal.getTabClients = () => [];
+ mockedInternal.syncTabs = () => Promise.resolve();
+
+ document.getElementById("sync-reauth-state").hidden = true;
+ document.getElementById("sync-setup-state").hidden = true;
+ document.getElementById("sync-syncnow-state").hidden = false;
+
+ CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
+
+ 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) {
+ for (let button = 0; button < 2; button++) {
+ yield PanelUI.show();
+ EventUtils.sendMouseEvent({ type: "click", button }, link, window);
+ // the panel should have been closed.
+ ok(!isPanelUIOpen(), "click closed the panel");
+ // should be a new tab - wait for the load.
+ is(gBrowser.tabs.length, 2, "there's a new tab");
+ yield new Promise(resolve => {
+ if (gBrowser.selectedBrowser.currentURI.spec == "about:blank") {
+ gBrowser.selectedBrowser.addEventListener("load", function listener(e) {
+ gBrowser.selectedBrowser.removeEventListener("load", listener, true);
+ resolve();
+ }, true);
+ return;
+ }
+ // the new tab has already transitioned away from about:blank so we
+ // are good to go.
+ resolve();
+ });
+
+ let os = link.getAttribute("mobile-promo-os");
+ let expectedUrl = `http://example.com/?os=${os}&tail=synced-tabs`;
+ is(gBrowser.selectedBrowser.currentURI.spec, expectedUrl, "correct URL");
+ gBrowser.removeTab(gBrowser.selectedTab);
+ }
+ }
+
+ // test each link and right mouse button - should be a noop.
+ yield PanelUI.show();
+ for (let link of links) {
+ EventUtils.sendMouseEvent({ type: "click", button: 2 }, link, window);
+ // the panel should still be open
+ ok(isPanelUIOpen(), "panel remains open after right-click");
+ is(gBrowser.tabs.length, 1, "no new tab was opened");
+ }
+ PanelUI.hide();
+
+ Services.prefs.clearUserPref("identity.mobilepromo.android");
+ Services.prefs.clearUserPref("identity.mobilepromo.ios");
+});
+
+// Test the "Sync Now" button
+add_task(function* () {
+ mockedInternal.getTabClients = () => [];
+ mockedInternal.syncTabs = () => {
+ return Promise.resolve();
+ }
+
+ // 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;
+
+ // add the Sync button to the panel
+ CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
+ yield PanelUI.show();
+ document.getElementById("sync-button").click();
+ let syncPanel = document.getElementById("PanelUI-remotetabs");
+ ok(syncPanel.getAttribute("current"), "Sync Panel is in view");
+
+ 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 = gSyncUI.doSync;
+ gSyncUI.doSync = function() {
+ didSync = true;
+ mockedInternal.hasSyncedThisSession = true;
+ gSyncUI.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([]);
+ }
+ yield 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([
+ {
+ id: "guid_mobile",
+ type: "client",
+ name: "My Phone",
+ tabs: [],
+ },
+ {
+ id: "guid_desktop",
+ type: "client",
+ name: "My Desktop",
+ tabs: [
+ {
+ title: "http://example.com/10",
+ lastUsed: 10, // the most recent
+ },
+ {
+ title: "http://example.com/1",
+ lastUsed: 1, // the least recent.
+ },
+ {
+ title: "http://example.com/5",
+ lastUsed: 5,
+ },
+ ],
+ },
+ {
+ id: "guid_second_desktop",
+ name: "My Other Desktop",
+ tabs: [
+ {
+ title: "http://example.com/6",
+ lastUsed: 6,
+ }
+ ],
+ },
+ ]);
+ };
+ yield updateTabsPanel();
+
+ // The UI should be showing tabs!
+ is(deck.selectedIndex, DECKINDEX_TABS, "no-clients deck entry is visible");
+ let tabList = document.getElementById("PanelUI-remotetabs-tabslist");
+ let node = tabList.firstChild;
+ // First entry should be the client with the most-recent tab.
+ is(node.getAttribute("itemtype"), "client", "node is a client entry");
+ is(node.textContent, "My Desktop", "correct client");
+ // Next entry is the most-recent tab
+ node = node.nextSibling;
+ is(node.getAttribute("itemtype"), "tab", "node is a tab");
+ is(node.getAttribute("label"), "http://example.com/10");
+
+ // Next entry is the next-most-recent tab
+ node = node.nextSibling;
+ is(node.getAttribute("itemtype"), "tab", "node is a tab");
+ is(node.getAttribute("label"), "http://example.com/5");
+
+ // Next entry is the least-recent tab from the first client.
+ node = node.nextSibling;
+ is(node.getAttribute("itemtype"), "tab", "node is a tab");
+ is(node.getAttribute("label"), "http://example.com/1");
+
+ // Next is a menuseparator between the clients.
+ node = node.nextSibling;
+ is(node.nodeName, "menuseparator");
+
+ // Next is the client with 1 tab.
+ node = node.nextSibling;
+ is(node.getAttribute("itemtype"), "client", "node is a client entry");
+ is(node.textContent, "My Other Desktop", "correct client");
+ // Its single tab
+ node = node.nextSibling;
+ is(node.getAttribute("itemtype"), "tab", "node is a tab");
+ is(node.getAttribute("label"), "http://example.com/6");
+
+ // Next is a menuseparator between the clients.
+ node = node.nextSibling;
+ is(node.nodeName, "menuseparator");
+
+ // Next is the client with no tab.
+ node = node.nextSibling;
+ is(node.getAttribute("itemtype"), "client", "node is a client entry");
+ is(node.textContent, "My Phone", "correct client");
+ // 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");
+});