Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
/* Any copyright is dedicated to the Public Domain.
"use strict";
add_setup(async function () {
await SpecialPowers.pushPrefEnv({
set: [["browser.urlbar.contextMenu.featureGate", true]],
});
// Add visits so that it can be autofilled.
await PlacesTestUtils.addVisits([
{
transition: PlacesUtils.history.TRANSITION_TYPED,
},
]);
await PlacesFrecencyRecalculator.recalculateAnyOutdatedFrecencies();
registerCleanupFunction(async () => {
await PlacesUtils.history.clear();
});
});
add_task(async function basic() {
const TEST_CASES = [
{
preferences: [["browser.tabs.loadInBackground", true]],
menuItemLabel: "Open in New Tab",
expectedTarget: "tab",
expectedOption: { background: true },
},
{
preferences: [["browser.tabs.loadInBackground", false]],
menuItemLabel: "Open in New Tab",
expectedTarget: "tab",
},
{
preferences: [["browser.tabs.loadInBackground", true]],
menuItemLabel: "Open in New Container Tab",
subMenuItemLabel: "Personal",
expectedTarget: "tab",
expectedOption: { background: true, userContextId: 1 },
},
{
preferences: [["browser.tabs.loadInBackground", false]],
menuItemLabel: "Open in New Container Tab",
subMenuItemLabel: "Banking",
expectedTarget: "tab",
expectedOption: { userContextId: 3 },
},
{
menuItemLabel: "Open in New Window",
expectedTarget: "window",
},
{
menuItemLabel: "Open in New Private Window",
expectedTarget: "window",
expectedOption: { private: true },
},
];
for (let {
preferences = [],
menuItemLabel,
subMenuItemLabel,
expectedTarget,
expectedOption = {},
} of TEST_CASES) {
info(`Test for %{JSON.stringify({ preferences, menuItem, subMenuItem })}`);
info("Set preferences");
await SpecialPowers.pushPrefEnv({ set: preferences });
info("Open urlbar results");
await UrlbarTestUtils.promiseAutocompleteResultPopup({
value: "exa",
window,
fireInputEvent: true,
});
let { element } = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
let onSuggestionOpen =
expectedTarget == "tab"
info("Open context menu");
let row = element.row;
let contextMenu = document.getElementById("urlbarView-context-menu");
let onMenuShown = BrowserTestUtils.waitForEvent(document, "popupshown");
EventUtils.synthesizeMouseAtCenter(row, {
button: 2,
type: "mousedown",
});
EventUtils.synthesizeMouseAtCenter(row, {
button: 2,
type: "contextmenu",
});
await onMenuShown;
info(`Select menu item '${menuItemLabel}'`);
let menuItem = [...contextMenu.children].find(
i => i.label == menuItemLabel
);
if (subMenuItemLabel) {
info(`Select sub menu item '${subMenuItemLabel}'`);
let onSubMenuShown = new Promise(resolve => {
menuItem.addEventListener("popupshown", resolve);
});
menuItem.openMenu(true);
await onSubMenuShown;
info(`Select sub menu item '${subMenuItemLabel}'`);
await TestUtils.waitForCondition(() =>
[...menuItem.menupopup.children].find(i => i.label == subMenuItemLabel)
);
let subMenuItem = [...menuItem.menupopup.children].find(
i => i.label == subMenuItemLabel
);
menuItem.menupopup.activateItem(subMenuItem, {});
} else {
contextMenu.activateItem(menuItem, {});
}
let target = await onSuggestionOpen;
switch (expectedTarget) {
case "tab": {
Assert.equal(Cu.getClassName(target, true), "XULElement");
Assert.equal(target.localName, "tab");
if (expectedOption.background) {
Assert.notEqual(target, gBrowser.selectedTab);
} else {
await TestUtils.waitForCondition(
() => target == gBrowser.selectedTab
);
Assert.equal(target, gBrowser.selectedTab);
}
if (expectedOption.userContextId) {
Assert.equal(
target.getAttribute("usercontextid"),
expectedOption.userContextId
);
} else {
Assert.ok(!target.hasAttribute("usercontextid"));
}
BrowserTestUtils.removeTab(target);
break;
}
case "window": {
Assert.equal(Cu.getClassName(target, true), "Window");
Assert.equal(
PrivateBrowsingUtils.isWindowPrivate(target),
!!expectedOption.private
);
target.close();
break;
}
}
}
await PlacesUtils.history.clear();
});
add_task(async function toolbar_context_menu() {
let TEST_TARGETS = [
".searchmode-switcher",
"#trust-icon-container",
"#identity-box",
];
for (let target of TEST_TARGETS) {
info(`Test for ${target}`);
let element = document.querySelector(target);
let onPopupShown = BrowserTestUtils.waitForEvent(document, "popupshown");
EventUtils.synthesizeMouseAtCenter(element, {
type: "contextmenu",
button: 2,
});
let { target: popup } = await onPopupShown;
Assert.equal(popup.id, "toolbar-context-menu");
popup.hidePopup();
}
});
});
add_task(async function no_context_menu() {
let TEST_DATA = [
{
featureGate: false,
target: ".urlbarView-row",
},
{
featureGate: false,
target: ".urlbar-background",
},
{
featureGate: true,
target: ".urlbar-background",
},
];
for (let { featureGate, target } of TEST_DATA) {
info(`Test for ${JSON.stringify({ featureGate, target })}`);
await SpecialPowers.pushPrefEnv({
set: [["browser.urlbar.contextMenu.featureGate", featureGate]],
});
await UrlbarTestUtils.promiseAutocompleteResultPopup({
value: "exa",
window,
fireInputEvent: true,
});
let onContextMenu = BrowserTestUtils.waitForEvent(window, "contextmenu");
let popupShown = false;
let popupListener = () => {
popupShown = true;
};
window.addEventListener("popupshowing", popupListener, true);
document.querySelector(target).dispatchEvent(
new PointerEvent("contextmenu", {
bubbles: true,
cancelable: true,
button: 2,
view: window,
})
);
info("Waiting for context menu");
let event = await onContextMenu;
Assert.ok(event.defaultPrevented);
Assert.ok(!popupShown);
window.removeEventListener("popupshowing", popupListener, true);
await SpecialPowers.popPrefEnv();
}
});
// Neither activateItem() nor dispatching a "click" triggers a mousedown, so
// this test dispatches a bare mousedown to verify that the view stays open
// when a mousedown is fired on the context menu. It does not actually open the
// result, since a menu item isn't activated by a mousedown alone. Real-clicking
// a context menu item isn't feasible cross-platform (on macOS the native menu
// item has no layout box, and synthesizing a click crashes on Windows), so we
// scope this test to the mousedown behavior only.
add_task(async function keep_view_open_on_context_menu_mousedown() {
info("Open urlbar results");
await UrlbarTestUtils.promiseAutocompleteResultPopup({
value: "exa",
window,
fireInputEvent: true,
});
let { element } = await UrlbarTestUtils.getDetailsOfResultAt(window, 0);
info("Open context menu");
let contextMenu = document.getElementById("urlbarView-context-menu");
let onMenuShown = BrowserTestUtils.waitForEvent(document, "popupshown");
EventUtils.synthesizeMouseAtCenter(element.row, {
button: 2,
type: "mousedown",
});
EventUtils.synthesizeMouseAtCenter(element.row, {
button: 2,
type: "contextmenu",
});
await onMenuShown;
Assert.ok(
gURLBar.view.isOpen,
"The view should remain open after the context menu is shown"
);
info("Mouse down on a context menu item");
let menuItem = [...contextMenu.children].find(
i => i.label == "Open in New Tab"
);
menuItem.dispatchEvent(
new MouseEvent("mousedown", { bubbles: true, button: 0, view: window })
);
Assert.ok(
gURLBar.view.isOpen,
"The view stays open after a mousedown on the context menu"
);
contextMenu.hidePopup();
gURLBar.view.close();
});