582 lines
20 KiB
JavaScript
582 lines
20 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
"use strict";
|
|
|
|
/**
|
|
* Test the keyboard behavior of PanelViews.
|
|
*/
|
|
|
|
const kEmbeddedDocUrl =
|
|
'data:text/html,<textarea id="docTextarea">value</textarea><button id="docButton"></button>';
|
|
|
|
let gAnchor;
|
|
let gPanel;
|
|
let gPanelMultiView;
|
|
let gMainView;
|
|
let gMainContext;
|
|
let gMainButton1;
|
|
let gMainMenulist;
|
|
let gMainRadiogroup;
|
|
let gMainTextbox;
|
|
let gMainButton2;
|
|
let gMainButton3;
|
|
let gCheckbox;
|
|
let gNamespacedLink;
|
|
let gLink;
|
|
let gMainTabOrder;
|
|
let gMainArrowOrder;
|
|
let gSubView;
|
|
let gSubButton;
|
|
let gSubTextarea;
|
|
let gBrowserView;
|
|
let gBrowserBrowser;
|
|
let gIframeView;
|
|
let gIframeIframe;
|
|
let gToggle;
|
|
|
|
async function openPopup() {
|
|
let shown = BrowserTestUtils.waitForEvent(gMainView, "ViewShown");
|
|
PanelMultiView.openPopup(gPanel, gAnchor, "bottomright topright");
|
|
await shown;
|
|
}
|
|
|
|
async function hidePopup() {
|
|
let hidden = BrowserTestUtils.waitForEvent(gPanel, "popuphidden");
|
|
PanelMultiView.hidePopup(gPanel);
|
|
await hidden;
|
|
}
|
|
|
|
async function showSubView(view = gSubView) {
|
|
let shown = BrowserTestUtils.waitForEvent(view, "ViewShown");
|
|
// We must show with an anchor so the Back button is generated.
|
|
gPanelMultiView.showSubView(view, gMainButton1);
|
|
await shown;
|
|
}
|
|
|
|
async function expectFocusAfterKey(aKey, aFocus) {
|
|
let res = aKey.match(/^(Shift\+)?(.+)$/);
|
|
let shift = Boolean(res[1]);
|
|
let key;
|
|
if (res[2].length == 1) {
|
|
key = res[2]; // Character.
|
|
} else {
|
|
key = "KEY_" + res[2]; // Tab, ArrowRight, etc.
|
|
}
|
|
info("Waiting for focus on " + aFocus.id);
|
|
let focused = BrowserTestUtils.waitForEvent(aFocus, "focus");
|
|
EventUtils.synthesizeKey(key, { shiftKey: shift });
|
|
await focused;
|
|
ok(true, aFocus.id + " focused after " + aKey + " pressed");
|
|
}
|
|
|
|
add_setup(async function () {
|
|
// This shouldn't be necessary - but it is, because we use same-process frames.
|
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1565276 covers improving this.
|
|
await SpecialPowers.pushPrefEnv({
|
|
set: [["security.allow_unsafe_parent_loads", true]],
|
|
});
|
|
let navBar = document.getElementById("nav-bar");
|
|
gAnchor = document.createXULElement("toolbarbutton");
|
|
navBar.appendChild(gAnchor);
|
|
gPanel = document.createXULElement("panel");
|
|
navBar.appendChild(gPanel);
|
|
gPanelMultiView = document.createXULElement("panelmultiview");
|
|
gPanelMultiView.setAttribute("mainViewId", "testMainView");
|
|
gPanel.appendChild(gPanelMultiView);
|
|
|
|
gMainView = document.createXULElement("panelview");
|
|
gMainView.id = "testMainView";
|
|
gPanelMultiView.appendChild(gMainView);
|
|
gMainContext = document.createXULElement("menupopup");
|
|
gMainContext.id = "gMainContext";
|
|
gMainView.appendChild(gMainContext);
|
|
gMainContext.appendChild(document.createXULElement("menuitem"));
|
|
gMainButton1 = document.createXULElement("button");
|
|
gMainButton1.id = "gMainButton1";
|
|
gMainView.appendChild(gMainButton1);
|
|
// We use this for anchoring subviews, so it must have a label.
|
|
gMainButton1.setAttribute("label", "gMainButton1");
|
|
gMainButton1.setAttribute("context", "gMainContext");
|
|
gMainMenulist = document.createXULElement("menulist");
|
|
gMainMenulist.id = "gMainMenulist";
|
|
gMainView.appendChild(gMainMenulist);
|
|
let menuPopup = document.createXULElement("menupopup");
|
|
gMainMenulist.appendChild(menuPopup);
|
|
let item = document.createXULElement("menuitem");
|
|
item.setAttribute("value", "1");
|
|
item.setAttribute("selected", "true");
|
|
menuPopup.appendChild(item);
|
|
item = document.createXULElement("menuitem");
|
|
item.setAttribute("value", "2");
|
|
menuPopup.appendChild(item);
|
|
gMainRadiogroup = document.createXULElement("radiogroup");
|
|
gMainRadiogroup.id = "gMainRadiogroup";
|
|
gMainView.appendChild(gMainRadiogroup);
|
|
let radio = document.createXULElement("radio");
|
|
radio.setAttribute("value", "1");
|
|
radio.setAttribute("selected", "true");
|
|
gMainRadiogroup.appendChild(radio);
|
|
radio = document.createXULElement("radio");
|
|
radio.setAttribute("value", "2");
|
|
gMainRadiogroup.appendChild(radio);
|
|
gMainTextbox = document.createElement("input");
|
|
gMainTextbox.id = "gMainTextbox";
|
|
gMainView.appendChild(gMainTextbox);
|
|
gMainTextbox.setAttribute("value", "value");
|
|
gMainButton2 = document.createXULElement("button");
|
|
gMainButton2.id = "gMainButton2";
|
|
gMainView.appendChild(gMainButton2);
|
|
gMainButton3 = document.createXULElement("button");
|
|
gMainButton3.id = "gMainButton3";
|
|
gMainView.appendChild(gMainButton3);
|
|
gCheckbox = document.createXULElement("checkbox");
|
|
gCheckbox.id = "gCheckbox";
|
|
gMainView.appendChild(gCheckbox);
|
|
|
|
// moz-support-links in XUL documents are created with the
|
|
// <html:a> tag and so we need to test this separately from
|
|
// <a> tags.
|
|
gNamespacedLink = document.createElementNS(
|
|
"http://www.w3.org/1999/xhtml",
|
|
"html:a"
|
|
);
|
|
gNamespacedLink.href = "www.mozilla.org";
|
|
gNamespacedLink.innerText = "gNamespacedLink";
|
|
gNamespacedLink.id = "gNamespacedLink";
|
|
gMainView.appendChild(gNamespacedLink);
|
|
gLink = document.createElement("a");
|
|
gLink.href = "www.mozilla.org";
|
|
gLink.innerText = "gLink";
|
|
gLink.id = "gLink";
|
|
gMainView.appendChild(gLink);
|
|
gToggle = document.createElement("moz-toggle");
|
|
gToggle.label = "Test label";
|
|
gMainView.appendChild(gToggle);
|
|
|
|
gMainTabOrder = [
|
|
gMainButton1,
|
|
gMainMenulist,
|
|
gMainRadiogroup,
|
|
gMainTextbox,
|
|
gMainButton2,
|
|
gMainButton3,
|
|
gCheckbox,
|
|
gNamespacedLink,
|
|
gLink,
|
|
gToggle,
|
|
];
|
|
gMainArrowOrder = [
|
|
gMainButton1,
|
|
gMainButton2,
|
|
gMainButton3,
|
|
gCheckbox,
|
|
gNamespacedLink,
|
|
gLink,
|
|
gToggle,
|
|
];
|
|
|
|
gSubView = document.createXULElement("panelview");
|
|
gSubView.id = "testSubView";
|
|
gPanelMultiView.appendChild(gSubView);
|
|
gSubButton = document.createXULElement("button");
|
|
gSubView.appendChild(gSubButton);
|
|
gSubTextarea = document.createElementNS(
|
|
"http://www.w3.org/1999/xhtml",
|
|
"textarea"
|
|
);
|
|
gSubTextarea.id = "gSubTextarea";
|
|
gSubView.appendChild(gSubTextarea);
|
|
gSubTextarea.value = "value";
|
|
|
|
gBrowserView = document.createXULElement("panelview");
|
|
gBrowserView.id = "testBrowserView";
|
|
gPanelMultiView.appendChild(gBrowserView);
|
|
gBrowserBrowser = document.createXULElement("browser");
|
|
gBrowserBrowser.id = "GBrowserBrowser";
|
|
gBrowserBrowser.setAttribute("type", "content");
|
|
gBrowserBrowser.setAttribute("src", kEmbeddedDocUrl);
|
|
gBrowserBrowser.style.minWidth = gBrowserBrowser.style.minHeight = "100px";
|
|
gBrowserView.appendChild(gBrowserBrowser);
|
|
|
|
gIframeView = document.createXULElement("panelview");
|
|
gIframeView.id = "testIframeView";
|
|
gPanelMultiView.appendChild(gIframeView);
|
|
gIframeIframe = document.createXULElement("iframe");
|
|
gIframeIframe.id = "gIframeIframe";
|
|
gIframeIframe.setAttribute("src", kEmbeddedDocUrl);
|
|
gIframeView.appendChild(gIframeIframe);
|
|
|
|
registerCleanupFunction(() => {
|
|
gAnchor.remove();
|
|
gPanel.remove();
|
|
});
|
|
});
|
|
|
|
// Test that the tab key focuses all expected controls.
|
|
add_task(async function testTab() {
|
|
await openPopup();
|
|
for (let elem of gMainTabOrder) {
|
|
await expectFocusAfterKey("Tab", elem);
|
|
}
|
|
// Wrap around.
|
|
await expectFocusAfterKey("Tab", gMainTabOrder[0]);
|
|
await hidePopup();
|
|
});
|
|
|
|
// Test that the shift+tab key focuses all expected controls.
|
|
add_task(async function testShiftTab() {
|
|
await openPopup();
|
|
for (let i = gMainTabOrder.length - 1; i >= 0; --i) {
|
|
await expectFocusAfterKey("Shift+Tab", gMainTabOrder[i]);
|
|
}
|
|
// Wrap around.
|
|
await expectFocusAfterKey(
|
|
"Shift+Tab",
|
|
gMainTabOrder[gMainTabOrder.length - 1]
|
|
);
|
|
await hidePopup();
|
|
});
|
|
|
|
// Test that the down arrow key skips menulists and textboxes.
|
|
add_task(async function testDownArrow() {
|
|
await openPopup();
|
|
for (let elem of gMainArrowOrder) {
|
|
await expectFocusAfterKey("ArrowDown", elem);
|
|
}
|
|
// Wrap around.
|
|
await expectFocusAfterKey("ArrowDown", gMainArrowOrder[0]);
|
|
await hidePopup();
|
|
});
|
|
|
|
// Test that the up arrow key skips menulists and textboxes.
|
|
add_task(async function testUpArrow() {
|
|
await openPopup();
|
|
for (let i = gMainArrowOrder.length - 1; i >= 0; --i) {
|
|
await expectFocusAfterKey("ArrowUp", gMainArrowOrder[i]);
|
|
}
|
|
// Wrap around.
|
|
await expectFocusAfterKey(
|
|
"ArrowUp",
|
|
gMainArrowOrder[gMainArrowOrder.length - 1]
|
|
);
|
|
await hidePopup();
|
|
});
|
|
|
|
// Test that the home/end keys move to the first/last controls.
|
|
add_task(async function testHomeEnd() {
|
|
await openPopup();
|
|
await expectFocusAfterKey("Home", gMainArrowOrder[0]);
|
|
await expectFocusAfterKey("End", gMainArrowOrder[gMainArrowOrder.length - 1]);
|
|
await hidePopup();
|
|
});
|
|
|
|
// Test that the up/down arrow keys work as expected in menulists.
|
|
add_task(async function testArrowsMenulist() {
|
|
await openPopup();
|
|
gMainMenulist.focus();
|
|
is(document.activeElement, gMainMenulist, "menulist focused");
|
|
is(gMainMenulist.value, "1", "menulist initial value 1");
|
|
if (AppConstants.platform == "macosx") {
|
|
// On Mac, down/up arrows just open the menulist.
|
|
let popup = gMainMenulist.menupopup;
|
|
for (let key of ["ArrowDown", "ArrowUp"]) {
|
|
let shown = BrowserTestUtils.waitForEvent(popup, "popupshown");
|
|
EventUtils.synthesizeKey("KEY_" + key);
|
|
await shown;
|
|
ok(gMainMenulist.open, "menulist open after " + key);
|
|
let hidden = BrowserTestUtils.waitForEvent(popup, "popuphidden");
|
|
EventUtils.synthesizeKey("KEY_Escape");
|
|
await hidden;
|
|
ok(!gMainMenulist.open, "menulist closed after Escape");
|
|
}
|
|
} else {
|
|
// On other platforms, down/up arrows change the value without opening the
|
|
// menulist.
|
|
EventUtils.synthesizeKey("KEY_ArrowDown");
|
|
is(
|
|
document.activeElement,
|
|
gMainMenulist,
|
|
"menulist still focused after ArrowDown"
|
|
);
|
|
is(gMainMenulist.value, "2", "menulist value 2 after ArrowDown");
|
|
EventUtils.synthesizeKey("KEY_ArrowUp");
|
|
is(
|
|
document.activeElement,
|
|
gMainMenulist,
|
|
"menulist still focused after ArrowUp"
|
|
);
|
|
is(gMainMenulist.value, "1", "menulist value 1 after ArrowUp");
|
|
}
|
|
await hidePopup();
|
|
});
|
|
|
|
// Test that the tab key closes an open menu list.
|
|
add_task(async function testTabOpenMenulist() {
|
|
await openPopup();
|
|
gMainMenulist.focus();
|
|
is(document.activeElement, gMainMenulist, "menulist focused");
|
|
let popup = gMainMenulist.menupopup;
|
|
let shown = BrowserTestUtils.waitForEvent(popup, "popupshown");
|
|
gMainMenulist.open = true;
|
|
await shown;
|
|
ok(gMainMenulist.open, "menulist open");
|
|
let menuHidden = BrowserTestUtils.waitForEvent(popup, "popuphidden");
|
|
EventUtils.synthesizeKey("KEY_Tab");
|
|
await menuHidden;
|
|
ok(!gMainMenulist.open, "menulist closed after Tab");
|
|
is(gPanel.state, "open", "Panel should be open");
|
|
await hidePopup();
|
|
});
|
|
|
|
if (AppConstants.platform == "macosx") {
|
|
// Test that using the mouse to open a menulist still allows keyboard navigation
|
|
// inside it.
|
|
add_task(async function testNavigateMouseOpenedMenulist() {
|
|
await openPopup();
|
|
let popup = gMainMenulist.menupopup;
|
|
let shown = BrowserTestUtils.waitForEvent(popup, "popupshown");
|
|
gMainMenulist.open = true;
|
|
await shown;
|
|
ok(gMainMenulist.open, "menulist open");
|
|
let oldFocus = document.activeElement;
|
|
let oldSelectedItem = gMainMenulist.selectedItem;
|
|
ok(
|
|
oldSelectedItem.hasAttribute("_moz-menuactive"),
|
|
"Selected item should show up as active"
|
|
);
|
|
EventUtils.synthesizeKey("KEY_ArrowDown");
|
|
await TestUtils.waitForCondition(
|
|
() => !oldSelectedItem.hasAttribute("_moz-menuactive")
|
|
);
|
|
is(oldFocus, document.activeElement, "Focus should not move on mac");
|
|
ok(
|
|
!oldSelectedItem.hasAttribute("_moz-menuactive"),
|
|
"Selected item should change"
|
|
);
|
|
|
|
let menuHidden = BrowserTestUtils.waitForEvent(popup, "popuphidden");
|
|
EventUtils.synthesizeKey("KEY_Tab");
|
|
await menuHidden;
|
|
ok(!gMainMenulist.open, "menulist closed after Tab");
|
|
is(gPanel.state, "open", "Panel should be open");
|
|
await hidePopup();
|
|
});
|
|
}
|
|
|
|
// Test that the up/down arrow keys work as expected in radiogroups.
|
|
add_task(async function testArrowsRadiogroup() {
|
|
await openPopup();
|
|
gMainRadiogroup.focus();
|
|
is(document.activeElement, gMainRadiogroup, "radiogroup focused");
|
|
is(gMainRadiogroup.value, "1", "radiogroup initial value 1");
|
|
EventUtils.synthesizeKey("KEY_ArrowDown");
|
|
is(
|
|
document.activeElement,
|
|
gMainRadiogroup,
|
|
"radiogroup still focused after ArrowDown"
|
|
);
|
|
is(gMainRadiogroup.value, "2", "radiogroup value 2 after ArrowDown");
|
|
EventUtils.synthesizeKey("KEY_ArrowUp");
|
|
is(
|
|
document.activeElement,
|
|
gMainRadiogroup,
|
|
"radiogroup still focused after ArrowUp"
|
|
);
|
|
is(gMainRadiogroup.value, "1", "radiogroup value 1 after ArrowUp");
|
|
await hidePopup();
|
|
});
|
|
|
|
// Test that pressing space in a textbox inserts a space (instead of trying to
|
|
// activate the control).
|
|
add_task(async function testSpaceTextbox() {
|
|
await openPopup();
|
|
gMainTextbox.focus();
|
|
gMainTextbox.selectionStart = gMainTextbox.selectionEnd = 0;
|
|
EventUtils.synthesizeKey(" ");
|
|
is(gMainTextbox.value, " value", "Space typed into textbox");
|
|
gMainTextbox.value = "value";
|
|
await hidePopup();
|
|
});
|
|
|
|
// Tests that the left arrow key normally moves back to the previous view.
|
|
add_task(async function testLeftArrow() {
|
|
await openPopup();
|
|
await showSubView();
|
|
let shown = BrowserTestUtils.waitForEvent(gMainView, "ViewShown");
|
|
EventUtils.synthesizeKey("KEY_ArrowLeft");
|
|
await shown;
|
|
ok("Moved to previous view after ArrowLeft");
|
|
await hidePopup();
|
|
});
|
|
|
|
// Tests that the left arrow key moves the caret in a textarea in a subview
|
|
// (instead of going back to the previous view).
|
|
add_task(async function testLeftArrowTextarea() {
|
|
await openPopup();
|
|
await showSubView();
|
|
gSubTextarea.focus();
|
|
is(document.activeElement, gSubTextarea, "textarea focused");
|
|
EventUtils.synthesizeKey("KEY_End");
|
|
is(gSubTextarea.selectionStart, 5, "selectionStart 5 after End");
|
|
EventUtils.synthesizeKey("KEY_ArrowLeft");
|
|
is(gSubTextarea.selectionStart, 4, "selectionStart 4 after ArrowLeft");
|
|
is(document.activeElement, gSubTextarea, "textarea still focused");
|
|
await hidePopup();
|
|
});
|
|
|
|
// Test navigation to a button which is initially disabled and later enabled.
|
|
add_task(async function testDynamicButton() {
|
|
gMainButton2.disabled = true;
|
|
await openPopup();
|
|
await expectFocusAfterKey("ArrowDown", gMainButton1);
|
|
await expectFocusAfterKey("ArrowDown", gMainButton3);
|
|
gMainButton2.disabled = false;
|
|
await expectFocusAfterKey("ArrowUp", gMainButton2);
|
|
await hidePopup();
|
|
});
|
|
|
|
add_task(async function testActivation() {
|
|
function checkActivated(elem, activationFn, reason) {
|
|
let activated = false;
|
|
elem.onclick = function () {
|
|
activated = true;
|
|
};
|
|
activationFn();
|
|
ok(activated, "Should have activated button after " + reason);
|
|
elem.onclick = null;
|
|
}
|
|
await openPopup();
|
|
await expectFocusAfterKey("ArrowDown", gMainButton1);
|
|
checkActivated(
|
|
gMainButton1,
|
|
() => EventUtils.synthesizeKey("KEY_Enter"),
|
|
"pressing enter"
|
|
);
|
|
checkActivated(
|
|
gMainButton1,
|
|
() => EventUtils.synthesizeKey(" "),
|
|
"pressing space"
|
|
);
|
|
checkActivated(
|
|
gMainButton1,
|
|
() => EventUtils.synthesizeKey("KEY_Enter", { code: "NumpadEnter" }),
|
|
"pressing numpad enter"
|
|
);
|
|
await hidePopup();
|
|
});
|
|
|
|
// Test that keyboard activation works for buttons responding to mousedown
|
|
// events (instead of command or click). The Library button does this, for
|
|
// example.
|
|
add_task(async function testActivationMousedown() {
|
|
await openPopup();
|
|
await expectFocusAfterKey("ArrowDown", gMainButton1);
|
|
let activated = false;
|
|
gMainButton1.onmousedown = function () {
|
|
activated = true;
|
|
};
|
|
EventUtils.synthesizeKey(" ");
|
|
ok(activated, "mousedown activated after space");
|
|
gMainButton1.onmousedown = null;
|
|
await hidePopup();
|
|
});
|
|
|
|
// Test that tab and the arrow keys aren't overridden in embedded documents.
|
|
async function testTabArrowsEmbeddedDoc(aView, aEmbedder) {
|
|
await openPopup();
|
|
await showSubView(aView);
|
|
let doc = aEmbedder.contentDocument;
|
|
if (doc.readyState != "complete" || doc.location.href != kEmbeddedDocUrl) {
|
|
info(`Embedded doc readyState ${doc.readyState}, location ${doc.location}`);
|
|
info("Waiting for load on embedder");
|
|
// Browsers don't fire load events, and iframes don't fire load events in
|
|
// typeChrome windows. We can handle both by using a capturing event
|
|
// listener to capture the load event from the child document.
|
|
await BrowserTestUtils.waitForEvent(aEmbedder, "load", true);
|
|
// The original doc might have been a temporary about:blank, so fetch it
|
|
// again.
|
|
doc = aEmbedder.contentDocument;
|
|
}
|
|
is(doc.location.href, kEmbeddedDocUrl, "Embedded doc has correct URl");
|
|
let backButton = aView.querySelector(".subviewbutton-back");
|
|
backButton.id = "docBack";
|
|
await expectFocusAfterKey("Tab", backButton);
|
|
// Documents don't have an id property, but expectFocusAfterKey wants one.
|
|
doc.id = "doc";
|
|
await expectFocusAfterKey("Tab", doc);
|
|
// Make sure tab/arrows aren't overridden within the embedded document.
|
|
let textarea = doc.getElementById("docTextarea");
|
|
// Tab should really focus the textarea, but default tab handling seems to
|
|
// skip everything inside the embedder element when run in this test. This
|
|
// behaves as expected in real panels, though. Force focus to the textarea
|
|
// and then test from there.
|
|
textarea.focus();
|
|
is(doc.activeElement, textarea, "textarea focused");
|
|
is(textarea.selectionStart, 0, "selectionStart initially 0");
|
|
EventUtils.synthesizeKey("KEY_ArrowRight");
|
|
is(textarea.selectionStart, 1, "selectionStart 1 after ArrowRight");
|
|
EventUtils.synthesizeKey("KEY_ArrowLeft");
|
|
is(textarea.selectionStart, 0, "selectionStart 0 after ArrowLeft");
|
|
is(doc.activeElement, textarea, "textarea still focused");
|
|
let docButton = doc.getElementById("docButton");
|
|
await expectFocusAfterKey("Tab", docButton);
|
|
await hidePopup();
|
|
}
|
|
|
|
// Test that tab and the arrow keys aren't overridden in embedded browsers.
|
|
add_task(async function testTabArrowsBrowser() {
|
|
await testTabArrowsEmbeddedDoc(gBrowserView, gBrowserBrowser);
|
|
});
|
|
|
|
// Test that tab and the arrow keys aren't overridden in embedded iframes.
|
|
add_task(async function testTabArrowsIframe() {
|
|
await testTabArrowsEmbeddedDoc(gIframeView, gIframeIframe);
|
|
});
|
|
|
|
// Test that the arrow keys aren't overridden in context menus.
|
|
add_task(async function testArowsContext() {
|
|
await openPopup();
|
|
await expectFocusAfterKey("ArrowDown", gMainButton1);
|
|
let shown = BrowserTestUtils.waitForEvent(gMainContext, "popupshown");
|
|
// There's no cross-platform way to open a context menu from the keyboard.
|
|
gMainContext.openPopup(gMainButton1);
|
|
await shown;
|
|
let item = gMainContext.children[0];
|
|
ok(
|
|
!item.getAttribute("_moz-menuactive"),
|
|
"First context menu item initially inactive"
|
|
);
|
|
let active = BrowserTestUtils.waitForEvent(item, "DOMMenuItemActive");
|
|
EventUtils.synthesizeKey("KEY_ArrowDown");
|
|
await active;
|
|
ok(
|
|
item.getAttribute("_moz-menuactive"),
|
|
"First context menu item active after ArrowDown"
|
|
);
|
|
is(
|
|
document.activeElement,
|
|
gMainButton1,
|
|
"gMainButton1 still focused after ArrowDown"
|
|
);
|
|
let hidden = BrowserTestUtils.waitForEvent(gMainContext, "popuphidden");
|
|
gMainContext.hidePopup();
|
|
await hidden;
|
|
await hidePopup();
|
|
});
|
|
|
|
add_task(async function testMozToggle() {
|
|
await openPopup();
|
|
is(gToggle.pressed, false, "The toggle is not pressed initially.");
|
|
// Focus the toggle via keyboard navigation.
|
|
while (document.activeElement !== gToggle) {
|
|
EventUtils.synthesizeKey("KEY_Tab");
|
|
}
|
|
EventUtils.synthesizeKey(" ");
|
|
await gToggle.updateComplete;
|
|
is(gToggle.pressed, true, "Toggle pressed state changes via spacebar.");
|
|
EventUtils.synthesizeKey("KEY_Enter");
|
|
await gToggle.updateComplete;
|
|
is(gToggle.pressed, false, "Toggle pressed state changes via enter.");
|
|
await hidePopup();
|
|
});
|