362 lines
9.9 KiB
JavaScript
362 lines
9.9 KiB
JavaScript
/* 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) => {
|
|
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;
|
|
}
|