summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/sync/browser_contextmenu_sendtab.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/sync/browser_contextmenu_sendtab.js')
-rw-r--r--browser/base/content/test/sync/browser_contextmenu_sendtab.js362
1 files changed, 362 insertions, 0 deletions
diff --git a/browser/base/content/test/sync/browser_contextmenu_sendtab.js b/browser/base/content/test/sync/browser_contextmenu_sendtab.js
new file mode 100644
index 0000000000..4922869c1d
--- /dev/null
+++ b/browser/base/content/test/sync/browser_contextmenu_sendtab.js
@@ -0,0 +1,362 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const kForceOverflowWidthPx = 450;
+
+Services.scriptloader.loadSubScript(
+ "chrome://mochitests/content/browser/browser/base/content/test/general/head.js",
+ this
+);
+
+const fxaDevices = [
+ {
+ id: 1,
+ name: "Foo",
+ availableCommands: { "https://identity.mozilla.com/cmd/open-uri": "baz" },
+ lastAccessTime: Date.now(),
+ },
+ {
+ id: 2,
+ name: "Bar",
+ availableCommands: { "https://identity.mozilla.com/cmd/open-uri": "boo" },
+ lastAccessTime: Date.now() + 60000, // add 30min
+ },
+ {
+ id: 3,
+ name: "Baz",
+ clientRecord: "bar",
+ lastAccessTime: Date.now() + 120000, // add 60min
+ }, // Legacy send tab target (no availableCommands).
+ { id: 4, name: "Homer" }, // Incompatible target.
+];
+
+let [testTab] = gBrowser.visibleTabs;
+
+function updateTabContextMenu(tab = gBrowser.selectedTab) {
+ let menu = document.getElementById("tabContextMenu");
+ var evt = new Event("");
+ tab.dispatchEvent(evt);
+ // The TabContextMenu initializes its strings only on a focus or mouseover event.
+ // Calls focus event on the TabContextMenu early in the test
+ gBrowser.selectedTab.focus();
+ menu.openPopup(tab, "end_after", 0, 0, true, false, evt);
+ is(
+ window.TabContextMenu.contextTab,
+ tab,
+ "TabContextMenu context is the expected tab"
+ );
+ menu.hidePopup();
+}
+
+add_setup(async function () {
+ await promiseSyncReady();
+ await Services.search.init();
+ // gSync.init() is called in a requestIdleCallback. Force its initialization.
+ gSync.init();
+ sinon
+ .stub(Weave.Service.clientsEngine, "getClientByFxaDeviceId")
+ .callsFake(fxaDeviceId => {
+ let target = fxaDevices.find(c => c.id == fxaDeviceId);
+ return target ? target.clientRecord : null;
+ });
+ sinon.stub(Weave.Service.clientsEngine, "getClientType").returns("desktop");
+ await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
+ registerCleanupFunction(() => {
+ gBrowser.removeCurrentTab();
+ });
+ is(gBrowser.visibleTabs.length, 2, "there are two visible tabs");
+});
+
+add_task(async function test_sendTabToDevice_callsFlushLogFile() {
+ const sandbox = setupSendTabMocks({ fxaDevices });
+ updateTabContextMenu(testTab);
+ await openTabContextMenu("context_sendTabToDevice");
+ let promiseObserved = promiseObserver("service:log-manager:flush-log-file");
+
+ await activateMenuItem();
+ await promiseObserved;
+ ok(true, "Got flush-log-file observer message");
+
+ await closeConfirmationHint();
+ sandbox.restore();
+});
+
+async function checkForConfirmationHint(targetId) {
+ const sandbox = setupSendTabMocks({ fxaDevices });
+ updateTabContextMenu(testTab);
+
+ await openTabContextMenu("context_sendTabToDevice");
+ await activateMenuItem();
+ is(
+ ConfirmationHint._panel.anchorNode.id,
+ targetId,
+ `Hint anchored to ${targetId}`
+ );
+ await closeConfirmationHint();
+ sandbox.restore();
+}
+
+add_task(async function test_sendTabToDevice_showsConfirmationHint_fxa() {
+ // We need to change the fxastatus from "not_configured" to show the FxA button.
+ is(
+ document.documentElement.getAttribute("fxastatus"),
+ "not_configured",
+ "FxA button is hidden"
+ );
+ document.documentElement.setAttribute("fxastatus", "foo");
+ await checkForConfirmationHint("fxa-toolbar-menu-button");
+ document.documentElement.setAttribute("fxastatus", "not_configured");
+});
+
+add_task(
+ async function test_sendTabToDevice_showsConfirmationHint_onOverflowMenu() {
+ // We need to change the fxastatus from "not_configured" to show the FxA button.
+ is(
+ document.documentElement.getAttribute("fxastatus"),
+ "not_configured",
+ "FxA button is hidden"
+ );
+ document.documentElement.setAttribute("fxastatus", "foo");
+
+ let navbar = document.getElementById("nav-bar");
+
+ // Resize the window so that the account button is in the overflow menu.
+ let originalWidth = window.outerWidth;
+ window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
+ await TestUtils.waitForCondition(() => navbar.hasAttribute("overflowing"));
+
+ await checkForConfirmationHint("PanelUI-menu-button");
+ document.documentElement.setAttribute("fxastatus", "not_configured");
+
+ window.resizeTo(originalWidth, window.outerHeight);
+ await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing"));
+ CustomizableUI.reset();
+ }
+);
+
+add_task(async function test_sendTabToDevice_showsConfirmationHint_appMenu() {
+ // If fxastatus is "not_configured" then the FxA button is hidden, and we
+ // should use the appMenu.
+ is(
+ document.documentElement.getAttribute("fxastatus"),
+ "not_configured",
+ "FxA button is hidden"
+ );
+ await checkForConfirmationHint("PanelUI-menu-button");
+});
+
+add_task(async function test_tab_contextmenu() {
+ const sandbox = setupSendTabMocks({ fxaDevices });
+ let expectation = sandbox
+ .mock(gSync)
+ .expects("sendTabToDevice")
+ .once()
+ .withExactArgs(
+ "about:mozilla",
+ [fxaDevices[1]],
+ "The Book of Mozilla, 6:27"
+ )
+ .returns(true);
+
+ updateTabContextMenu(testTab);
+ await openTabContextMenu("context_sendTabToDevice");
+ is(
+ document.getElementById("context_sendTabToDevice").hidden,
+ false,
+ "Send tab to device is shown"
+ );
+ is(
+ document.getElementById("context_sendTabToDevice").disabled,
+ false,
+ "Send tab to device is enabled"
+ );
+
+ await activateMenuItem();
+ await closeConfirmationHint();
+
+ expectation.verify();
+ sandbox.restore();
+});
+
+add_task(async function test_tab_contextmenu_unconfigured() {
+ const sandbox = setupSendTabMocks({ state: UIState.STATUS_NOT_CONFIGURED });
+
+ updateTabContextMenu(testTab);
+ is(
+ document.getElementById("context_sendTabToDevice").hidden,
+ true,
+ "Send tab to device is hidden"
+ );
+ is(
+ document.getElementById("context_sendTabToDevice").disabled,
+ false,
+ "Send tab to device is enabled"
+ );
+
+ sandbox.restore();
+});
+
+add_task(async function test_tab_contextmenu_not_sendable() {
+ const sandbox = setupSendTabMocks({ fxaDevices, isSendableURI: false });
+
+ updateTabContextMenu(testTab);
+ is(
+ document.getElementById("context_sendTabToDevice").hidden,
+ true,
+ "Send tab to device is hidden"
+ );
+ is(
+ document.getElementById("context_sendTabToDevice").disabled,
+ true,
+ "Send tab to device is disabled"
+ );
+
+ sandbox.restore();
+});
+
+add_task(async function test_tab_contextmenu_not_synced_yet() {
+ const sandbox = setupSendTabMocks({ fxaDevices: null });
+
+ updateTabContextMenu(testTab);
+ is(
+ document.getElementById("context_sendTabToDevice").hidden,
+ true,
+ "Send tab to device is hidden"
+ );
+ is(
+ document.getElementById("context_sendTabToDevice").disabled,
+ true,
+ "Send tab to device is disabled"
+ );
+
+ sandbox.restore();
+});
+
+add_task(async function test_tab_contextmenu_sync_not_ready_configured() {
+ const sandbox = setupSendTabMocks({ syncReady: false });
+
+ updateTabContextMenu(testTab);
+ is(
+ document.getElementById("context_sendTabToDevice").hidden,
+ true,
+ "Send tab to device is hidden"
+ );
+ is(
+ document.getElementById("context_sendTabToDevice").disabled,
+ true,
+ "Send tab to device is disabled"
+ );
+
+ sandbox.restore();
+});
+
+add_task(async function test_tab_contextmenu_sync_not_ready_other_state() {
+ const sandbox = setupSendTabMocks({
+ syncReady: false,
+ state: UIState.STATUS_NOT_VERIFIED,
+ });
+
+ updateTabContextMenu(testTab);
+ is(
+ document.getElementById("context_sendTabToDevice").hidden,
+ true,
+ "Send tab to device is hidden"
+ );
+ is(
+ document.getElementById("context_sendTabToDevice").disabled,
+ false,
+ "Send tab to device is enabled"
+ );
+
+ sandbox.restore();
+});
+
+add_task(async function test_tab_contextmenu_fxa_disabled() {
+ const getter = sinon.stub(gSync, "FXA_ENABLED").get(() => false);
+ // Simulate onFxaDisabled() being called on window open.
+ gSync.onFxaDisabled();
+
+ updateTabContextMenu(testTab);
+ is(
+ document.getElementById("context_sendTabToDevice").hidden,
+ true,
+ "Send tab to device is hidden"
+ );
+
+ getter.restore();
+ [...document.querySelectorAll(".sync-ui-item")].forEach(
+ e => (e.hidden = false)
+ );
+});
+
+add_task(async function teardown() {
+ Weave.Service.clientsEngine.getClientByFxaDeviceId.restore();
+ Weave.Service.clientsEngine.getClientType.restore();
+});
+
+async function openTabContextMenu(openSubmenuId = null) {
+ const contextMenu = document.getElementById("tabContextMenu");
+ is(contextMenu.state, "closed", "checking if popup is closed");
+
+ const awaitPopupShown = BrowserTestUtils.waitForEvent(
+ contextMenu,
+ "popupshown"
+ );
+ EventUtils.synthesizeMouseAtCenter(gBrowser.selectedTab, {
+ type: "contextmenu",
+ button: 2,
+ });
+ await awaitPopupShown;
+
+ if (openSubmenuId) {
+ const menuPopup = document.getElementById(openSubmenuId).menupopup;
+ const menuPopupPromise = BrowserTestUtils.waitForEvent(
+ menuPopup,
+ "popupshown"
+ );
+ menuPopup.openPopup();
+ await menuPopupPromise;
+ }
+}
+
+function promiseObserver(topic) {
+ return new Promise(resolve => {
+ let obs = (aSubject, aTopic, aData) => {
+ Services.obs.removeObserver(obs, aTopic);
+ resolve(aSubject);
+ };
+ Services.obs.addObserver(obs, topic);
+ });
+}
+
+function waitForConfirmationHint() {
+ return BrowserTestUtils.waitForEvent(ConfirmationHint._panel, "popuphidden");
+}
+
+async function activateMenuItem() {
+ let popupHidden = BrowserTestUtils.waitForEvent(
+ document.getElementById("tabContextMenu"),
+ "popuphidden"
+ );
+ let hintShown = BrowserTestUtils.waitForEvent(
+ ConfirmationHint._panel,
+ "popupshown"
+ );
+ let menuitem = document
+ .getElementById("context_sendTabToDevicePopupMenu")
+ .querySelector("menuitem");
+ menuitem.closest("menupopup").activateItem(menuitem);
+ await popupHidden;
+ await hintShown;
+}
+
+async function closeConfirmationHint() {
+ let hintHidden = BrowserTestUtils.waitForEvent(
+ ConfirmationHint._panel,
+ "popuphidden"
+ );
+ ConfirmationHint._panel.hidePopup();
+ await hintHidden;
+}